/**
 * SCAYT v3.1.1689 master:98e0c39 #81
 * Copyright (c) 2000-2017 WebSpellChecker LLC All rights reserved.
 */

/*!
 * jQuip JavaScript Library v0.0.3
 * https://github.com/mythz/jquip
 *
 * Copyright, Demis Bellot
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 */

/*!
 * Rangy, a cross-browser JavaScript range and selection library
 * http://code.google.com/p/rangy/
 *
 * Copyright 2012, Tim Down
 * Licensed under the MIT license.
 * Version: 1.3alpha.681
 * Build date: 20 July 2012
 */

/*! @license
 * JS Signals <http://millermedeiros.github.com/js-signals/>
 * Released under the MIT license
 * Author: Miller Medeiros
 * Version: 0.8.1 - Build: 266 (2012/07/31 03:33 PM)
 */
var SCAYT = SCAYT ||
    function(a) {
        function b(a) {
            if ("string" == typeof g.options[a].value) if (g.options[a].value = g.options[a].value.replace(/ /g, ""), g.options[a].value = g.options[a].value.replace(/,/g, "|"), "" != g.options[a].value) for (var b = g.options[a].defaultValue.split("|"), c = 0; c < b.length; c++) g.options[a].value.match(new RegExp("\\b" + b[c] + "\\b", "g")) || (g.options[a].value = g.options[a].value + "|" + b[c]);
            else g.options[a].value = g.options[a].defaultValue;
            else g.options[a].value = g.options[a].defaultValue;
            return new RegExp("^(" + g.options[a].value + ")$", "i")
        }
        function c(a, b) {
            for (var c in a) b.register(c, a[c]), b.start(c)
        }
        function d(a, b) {
            var c = function() {
                    try {
                        f[a].instance = new f[a].creator(a, new SCAYT.Sandbox(a, b))
                    } catch (c) {
                        throw new Error("Could not create Module instance with id: " + a + " : " + c.message)
                    }
                    d(), e(), g()
                },
                d = function() {
                    f[a].instance.init && f[a].instance.init()
                },
                e = function() {
                    var b, c = f[a].instance;
                    if (c.decorator) {
                        if (b = f[c.decoratorFor], void 0 === b) throw new Error(a + "try to decorate undefined module " + c.decoratorFor + ".");
                        if (void 0 === c.decorate) throw new Error(a + "should define decorate method.");
                        f[c.decoratorFor].instance = c.decorate(b.instance)
                    }
                },
                g = function() {
                    f[a].ready = f[a].instance.async ? !1 : !0
                };
            return f[a].instance ? !1 : (c(a, b), !0)
        }
        function e(a) {
            for (var b in f) if (f[b].ready === !1) return a.allModulesReady = !1, a.allModulesReady;
            return a.allModulesReady = !0, a.getService("Communication").fire({
                moduleID: "SCAYT",
                eventType: "allModulesReady"
            }), a.allModulesReady
        }
        var f = {},
            g = this,
            h = function(a, b) {
                return {
                    value: void 0,
                    defaultValue: a,
                    storable: b
                }
            },
            i = {
                container: h(void 0, !1),
                originalContainer: h(void 0, !1),
                focused: h(!1, !1),
                leftMouseButtonPressed: h(!1, !1),
                deleteKeyButtonPressed: h(!1, !1),
                backspaceKeyButtonPressed: h(!1, !1),
                spaceKeyButtonPressed: h(!1, !1),
                enterKeyButtonPressed: h(!1, !1),
                debug: h(!1, !1),
                wordsLimit: h(5, !1),
                spellCheckDelay: h(7e3, !1),
                isIframe: h(!1, !1),
                isPaidVersion: h(!0, !1),
                isServiceHostDefault: h(!0, !1),
                customer_id: h("1:WvF0D4-UtPqN1-43nkD4-NKvUm2-daQqk3-LmNiI-z7Ysb4-mwry24-T8YrS3-Q2tpq2", !1),
                basePath: h("", !1),
                main_WSC_domain: h("webspellchecker.net", !1),
                service_protocol: h("http", !1),
                service_host: h("svc.webspellchecker.net", !1),
                service_port: h("80", !1),
                service_path: h("spellcheck31/script/ssrv.cgi", !1),
                data_attribute_name: h("data-scayt-word", !1),
                data_lang_attribute: h("data-scayt-lang", !1),
                misspelled_word_node: h("span", !1),
                misspelled_word_class: h("scayt-misspell-word", !1),
                punctuationRegExp: h(/,\^\$\*\+\?\=\!\:\|\\\/\(\)\[\]\{\}\>\<\@\%\&\#\;\_\~\u061F\u060C\u061B�\u0001-\u001F\u0080-\u00B6\u00B8-\u00BF\u2000-\u200A\u200C-\u266F\u2E00-\u2E7F /, !1),
                customPunctuation: h("", !1),
                wordBoundaryRegex: h(!1, !1),
                blockElementsRegex: h(/^(aside|br|img|caption|button|address|blockquote|body|center|dir|div|dl|fieldset|form|h[1-6]|hr|isindex|menu|noframes|noscript|ol|p|pre|table|ul|dd|dt|frameset|li|tbody|td|tfoot|th|thead|tr|html|select|option|sup|sub|input)$/i, !1),
                ignoreElementsRegex: h("style|script", !1),
                ignoreGraytElementsRegex: h("", !1),
                specialCharactersRegex: h(new RegExp("[" + String.fromCharCode(8203) + String.fromCharCode(65279) + "]+"), !1),
                paused: h(!1, !1),
                graytState: h(!1, !1),
                eventsBlockedState: h({}, !1),
                scaytLangList: h({}, !1),
                graytLangList: h({
                    ltr: {
                        en_GB: "British English",
                        en_US: "American English"
                    },
                    rtl: {}
                }, !1),
                "ignore-all-caps-words": h(!1, !0),
                "ignore-domain-names": h(!0, !0),
                "ignore-words-with-mixed-cases": h(!1, !0),
                "ignore-words-with-numbers": h(!1, !0),
                userDictionaryKey: h("scayt_user_dictionary", !1),
                userDictionaryNameKey: h("scayt_user_dictionary_name", !1),
                userDictionaryName: h(null, !1),
                scaytLogo: h("css/logo.gif", !1),
                scaytVersion: h("3.1.1689 master:98e0c39 #81", !1),
                scaytSupportUrl: h("http://wiki.webspellchecker.net/", !1),
                styles: h("", !1),
                lang: h("en_US", !0),
                maxSuggestionsDefault: h(5, !1),
                minWordLength: h(3, !1),
                permanentMinWordLength: h({
                    th_TH: 2,
                    ko_KR: 2
                }, !1),
                customDictionary: h("", !1),
                localizationPath: h("local/", !1),
                localizationList: h(["af", "ar", "bg", "bn", "bs", "ca", "cs", "cy", "da", "de", "el", "en-us", "en-au", "en-ca", "en-gb", "en", "eo", "es", "et", "eu", "fa", "fi", "fo", "fr-ca", "fr", "gl", "gu", "he", "hi", "hr", "hu", "is", "it", "ja", "ka", "km", "ko", "lt", "lv", "mk", "mn", "ms", "nb", "nl", "no", "pl", "pt-br", "pt", "ro", "ru", "sk", "sl", "sr-latn", "sr", "sv", "th", "tr", "ug", "uk", "ku", "vi", "zh-cn", "zh"], !1),
                localization: h("en", !1),
                cssPath: h("css/scayt.css", !1),
                uid: h(void 0, !1),
                detectLocalizationLanguage: h(!1, !1),
                supportLocale: h(!0, !1),
                documentContainer: h(void 0, !1),
                focusContainer: h(void 0, !1),
                currentDocument: h(void 0, !1),
                "options-to-restore": h(["lang", "ignore-all-caps-words", "ignore-domain-names", "ignore-words-with-mixed-cases", "ignore-words-with-numbers"], !1),
                problem_grammar_node: h("span", !1),
                problem_grammar_class: h("gramm-problem", !1),
                problem_grammar_data_attribute: h("data-grayt-phrase", !1),
                languagesMap: h({
                    sw: "sw_TZ",
                    zu: "zu_ZA",
                    sq: "sq_AL",
                    ar: "ar_SA",
                    es: "es_ES",
                    de: "de_DE",
                    wa: "wa_BE",
                    qu: "qu_EC",
                    bg: "bg_BG",
                    hr: "hr_HR",
                    sr: "sr_LT",
                    cs: "cs_CZ",
                    ln: "ln_CD",
                    hy: "hy_AM",
                    en: "en_US",
                    et: "et_EE",
                    ti: "ti_ER",
                    om: "om_ET",
                    fo: "fo_FO",
                    fj: "fj_FJ",
                    sv: "sv_SE",
                    br: "br_FR",
                    gd: "gd_GB",
                    ht: "ht_HT",
                    he: "he_HE",
                    hi: "hi_IN",
                    hu: "hu_HU",
                    is: "is_IS",
                    as: "as_IN",
                    or: "or_IN",
                    id: "id_ID",
                    tet: "tet_ID",
                    fa: "fa_IR",
                    ga: "ga_IE",
                    gv: "gv_GB",
                    kk: "kk_KZ",
                    ky: "ky_KG",
                    lv: "lv_LV",
                    lt: "lt_LT",
                    lb: "lb_LU",
                    mi: "mi_NZ",
                    mg: "mg_MG",
                    ms: "ms_MY",
                    mn: "mn_MN",
                    ha: "ha_GH",
                    ur: "ur_PK",
                    tl: "tl_PH",
                    pl: "pl_PL",
                    csb: "csb_PL",
                    ro: "ro_RO",
                    ru: "ru_RU",
                    cv: "cv_RU",
                    rw: "rw_RW",
                    sk: "sk_SK",
                    sl: "sl_SI",
                    so: "so_SO",
                    cy: "cy_GB",
                    af: "af_ZA",
                    ss: "ss_ZA",
                    ts: "ts_ZA",
                    ve: "ve_ZA",
                    xh: "xh_ZA",
                    an: "an_ES",
                    ast: "ast_ES",
                    ca: "ca_ES",
                    gl: "gl_ES",
                    si: "si_LK",
                    tt: "tt_RU",
                    tpi: "tpi_PG",
                    th: "th_TH",
                    tr: "tr_TR",
                    ku: "ku_TR",
                    tk: "tk_TM",
                    uk: "uk_UA",
                    uz: "uz_UZ",
                    vi: "vi_VN",
                    sn: "sn_ZW",
                    eo: "eo_EO",
                    da: "da_DK",
                    fi: "fi_FI",
                    fr: "fr_FR",
                    it: "it_IT",
                    nl: "nl_NL",
                    pt: "pt_PT",
                    shs: "shs_CA",
                    mos: "mo_BF",
                    gsc: "gsc_FR",
                    fur: "fu_IT",
                    hil: "hl_PH",
                    sh: "sh_YU",
                    nso: "ns_ZA",
                    tn: "tn_ZA",
                    az: "az_AZ",
                    oc: "oc_FR",
                    grc: "grc_GR",
                    smj: "smj_NO",
                    fy: "fy_NL",
                    nn: "nn_NO",
                    se: "se_NO",
                    nr: "nr_ZA",
                    st: "st_ZA",
                    ia: "ia_XR",
                    el: "el_GR",
                    nb: "nb_NO",
                    ko: "ko_KR",
                    la: "la_VA",
                    mr: "mr_IN",
                    son: "son_ML",
                    bn: "bn_IN",
                    mk: "mk_MK",
                    be: "be_BY",
                    dsb: "dsb_DE",
                    hsb: "hsb_DE",
                    sa: "sa_IN",
                    te: "te_IN",
                    ta: "ta_IN",
                    ne: "ne_NP",
                    yi: "yi_YI"
                }, !1),
                languageNodeName: h("span", !1),
                languageAttributeName: h("lang", !1),
                multiLanguageMode: h(!1, !1),
                maxLength: h(-1, !1),
                charsToObserve: h([], !1),
                shortcutsList: h([], !1),
                undoDataSize: h(20, !1),
                isTextBasedContainer: h(!0, !1),
                enableOnTouchDevices: h(!1, !1),
                contextMenuForMisspelledOnly: h(!1, !1),
                contextMenuByMouseover: h(!1, !1),
                isTouchDevice: h(!1, !1),
                bannerTemplate: h("", !1),
                bannerType: h("", !1),
                numberOfFailedRequest: h(0, !1)
            };
        delete a.words_separator, delete a.paused, delete a.eventsBlockedState, delete a.scaytLangList, delete a.graytLangList, delete a.uid, delete a.permanentMinWordLength, delete a.languagesMap, delete a.isPaidVersion, i.documentContainer.value = "[object String]" == Object.prototype.toString.call(a.container) ? document.getElementById(a.container) : a.container, i.isIframe.value = "iframe" == i.documentContainer.value.nodeName.toLowerCase() ? !0 : !1, i.currentDocument.value = i.isIframe.value === !0 ? i.documentContainer.value.contentWindow.document : document, i.basePath.value = a.basePath, i.cssPath.value = i.basePath.value ? this.Utils.getUrl(i.cssPath.defaultValue, i.basePath.value) : i.cssPath.defaultValue;
        var j = this.Utils.getLocationInfo(i.basePath.value);
        "file" != j.protocol && (i.service_protocol.value = j.protocol, i.service_host.value = j.host, i.service_port.value = j.port ? j.port : "80", i.service_path.value = j.pathname + "./../../../script/ssrv.cgi");
        for (var k in a) i[k] && (i[k].value = a[k]);
        for (k in i)"undefined" == typeof i[k].value && (i[k].value = i[k].defaultValue);
        this.options = i, this.options.localization.value = -1 == this.Utils.indexOf(this.options.localizationList.value, this.options.localization.value) ? this.options.localization.defaultValue : this.options.localization.value, "string" == typeof this.options.service_host.value && (this.options.isServiceHostDefault.value = -1 !== this.options.service_host.value.indexOf(this.options.main_WSC_domain.value) ? !0 : !1), this.options.container.value = "iframe" == this.options.documentContainer.value.nodeName.toLowerCase() ? this.options.documentContainer.value.contentDocument ? this.options.documentContainer.value.contentDocument.getElementsByTagName("body")[0] : this.options.documentContainer.value.contentWindow.document.getElementsByTagName("body")[0] : this.options.documentContainer.value, this.options.originalContainer.value = this.options.container.value, this.options.focusContainer.value = this.UILib.find(this.options.documentContainer.value.contentWindow || this.options.container.value)[0], this.options.uid.value = this.instanceManager.getUniqueId(this.options.documentContainer.value), this.options.ignoreElementsRegex.value = b("ignoreElementsRegex"), this.options.ignoreGraytElementsRegex.value = b("ignoreGraytElementsRegex"), this.options.customPunctuation.defaultValue !== this.options.customPunctuation.value && (this.options.punctuationRegExp.value = new RegExp(this.options.punctuationRegExp.value.source + this.options.customPunctuation.value)), this.options.wordBoundaryRegex.value = new RegExp("[" + /.\s\xA0/.source + this.options.punctuationRegExp.value.source + "]");
        for (var l, m, n = 0, o = this.options["options-to-restore"].value.length; o > n; n++) l = this.options["options-to-restore"].value[n], this.options[l] && this.options[l].storable && (m = this.DataStorage.getData(this.options.uid.value + "_" + l), "undefined" != typeof m && null !== m ? this.options[l].value = m : this.DataStorage.setData(this.options.uid.value + "_" + l, this.options[l].value));
        for (k in this.options) this.options[k].storable && -1 == this.Utils.indexOf(this.options["options-to-restore"].value, k) && this.DataStorage.deleteData(this.options.uid.value + "_" + k);
        var g = this,
            p = (this.UILib.find(this.options.container.value)[0], {
                Communication: SCAYT.Communication,
                DOMCommunication: SCAYT.DOMCommunication,
                RangeCreator: SCAYT.RangeCreator,
                Deferred: SCAYT.Deferred,
                StateController: SCAYT.StateController
            });
        this.allModulesReady = !1, this.register = function(a, b) {
            f[a] = f[a] || {
                    creator: b,
                    instance: null,
                    ready: !1
                }
        }, this.getService = function(a) {
            return f[a] ? f[a].instance : void 0
        }, this.start = function(a) {
            var b = "";
            b = d(a, this) ? a + " started." : a + " already started.", this.getService("Communication").fire({
                moduleID: "SCAYT",
                eventType: "moduleStarted",
                data: {
                    statusMessage: b
                }
            })
        }, this.initModules = function(a) {
            c(a, this), e(this)
        }, this.destroyModules = function(a) {
            a = a || f;
            for (var b in a) f[b].instance.destroy && f[b].instance.destroy();
            for (var b in a) f[b].instance = null
        }, c(p, this), this.getService("Communication").subscribe({
            moduleID: "SCAYT",
            eventType: "moduleReady",
            handler: function(a) {
                f[a.moduleID].ready = !0, e(this)
            },
            context: this
        })
    };
SCAYT.Sandbox = function(a, b) {
    function c(a, c) {
        var d = {};
        for (var e in a) a.hasOwnProperty(e) && -1 === b.Utils.indexOf(c, e) && (d[e] = b.Utils.bind(a[e], a));
        return d
    }
    function d(a, c) {
        var d = {};
        return c = b.Utils.argumentsToArray(c), d = b.Utils.is(c[0], "Object") ? c[0] : b.Utils.zipArraysToObject(a, c)
    }
    function e() {
        var a, b = this.getOption("leftMouseButtonPressed"),
            c = this.Utils.browser.ie;
        return a = c && b ? !1 : !0
    }
    this.getCommunication = function() {
        return b.getService("Communication")
    }, this.createRange = function() {
        var c = b.getService("RangeCreator").createRange();
        return b.logger.log({
            name: a,
            msg: "Create the range",
            data: c,
            type: "range"
        }), c
    }, this.getSelection = function(c) {
        var d = b.getService("RangeCreator").getSelection(c);
        return b.logger.log({
            name: a,
            msg: "Get the selection",
            data: d,
            type: "selection"
        }), d
    }, this.saveSelection = function() {
        var c;
        return e.apply(this) ? (c = b.getService("RangeCreator").getSelectionManager().saveSelection(), b.logger.log({
            name: a,
            msg: "Save the selection",
            data: c,
            type: "selection"
        }), c) : void 0
    }, this.restoreSelection = function(c) {
        var d;
        return c && e.apply(this) ? (d = b.getService("RangeCreator").getSelectionManager().restoreSelection(c), b.logger.log({
            name: a,
            msg: "Restore the selection",
            data: d,
            type: "selection"
        }), this.fire("selectionIsChanged", {
            action: "restoreSelection"
        }), d) : void 0
    }, this.deleteStoredSelection = function(a) {
        var b, c = !1;
        return a && (b = this.saveSelection(), this.restoreSelection(a), this.restoreSelection(b), c = !0), c
    }, this.removeMarkers = function(c) {
        var d = b.getService("RangeCreator").getSelectionManager().removeMarkers(c);
        return b.logger.log({
            name: a,
            msg: "Removes the hidden marker",
            data: d,
            type: "selection"
        }), d
    }, this.getBookmark = function() {
        var c, d, e;
        return e = b.getService("RangeCreator").getSelection(), e.rangeCount() ? (d = e.getRangeAt(0), c = d.getBookmark(this.getOption("container")), b.logger.log({
            name: a,
            msg: "Save the bookmark",
            data: c,
            type: "range"
        }), c) : void 0
    }, this.moveToBookmark = function(c) {
        var d;
        return c ? (d = b.getService("RangeCreator").createRange(), d = d.moveToBookmark(c), b.logger.log({
            name: a,
            msg: "Move to bookmark",
            data: d,
            type: "range"
        }), d) : void 0
    }, this.getCaretRangeFromEvent = function(a) {
        var b, c, d, e = a.clientX,
            f = a.clientY,
            g = "wsc-caret-" + (new Date).getTime(),
            h = this.createRange(),
            i = this.getSelection(),
            j = (i.rangeCount() > 0 ? i.getRangeAt(0) : void 0, this.Utils.getCurrentDocument(this.getOption("documentContainer"))),
            k = this.getOption("container");
        if (j.caretPositionFromPoint) d = j.caretPositionFromPoint(e, f), h.setStart(d.offsetNode, d.offset), h.collapse(!0);
        else if (j.caretRangeFromPoint) d = j.caretRangeFromPoint(e, f), h.setStart(d.startContainer, d.startOffset), h.collapse(!0);
        else if (j.body.createTextRange) {
            this.fire({
                element: k,
                eventType: "focus"
            }), b = j.body.createTextRange();
            try {
                b.moveToPoint(e, f), b.pasteHTML('<span id="' + g + '">​</span>'), c = this.UILib.find("#" + g, k)[0], h.setStartBefore(c), h.collapse(!0), this.UILib.remove(c)
            } catch (l) {
                return null
            }
        }
        return h
    }, this.IO = b.Utils.assign({}, b.IO), this.DOM = b.DOM, this.Utils = b.Utils, this.logger = b.logger.log, b.logger.isON(b.options.debug.value), this.console = b.logger.console, this.Localization = b.Localization, this.Template = b.Template, this.DataStorage = b.DataStorage, this.IO.get = function(a, c, d) {
        var e, f = b.getService("LimitationManager");
        return f ? void(e = f.inspect(a)) : b.IO.get(a, c, d)
    }, this.FullUILib = b.UILib;
    var f = ["cancelEvent", "preventDefault", "stopPropagation", "stopImmediatePropagation", "focus", "blur", "contextmenu", "on", "one", "off", "trigger"];
    this.UILib = c(this.FullUILib, f), this.DataProcessor = b.DataProcessor, this.blockEvents = function(a) {
        for (var b = this.getOption("eventsBlockedState"), c = 0; c < a.length; c++) b[a[c]] = !0;
        this.setOption("eventsBlockedState", b)
    }, this.unblockEvents = function(a) {
        for (var b = this.getOption("eventsBlockedState"), c = 0; c < a.length; c++) b[a[c]] = !1;
        this.setOption("eventsBlockedState", b)
    }, this.setPaused = function(a) {
        return b.options.paused.value = a
    }, this.fire = function() {
        var c = this.getOption("eventsBlockedState"),
            e = d(["eventType", "data", "instance", "DOMElement"], arguments);
        return e.moduleID = a, b.logger.log({
            name: a,
            msg: "Fired event: " + e.eventType + " with such data -> ",
            data: e.data,
            type: "signals"
        }), b.options.paused.value === !0 || c[e.eventType] ? void 0 : this.getCommunication().fire(e)
    }, this.subscribe = function() {
        var c = d(["eventType", "handler", "context", "priority", "instance", "element"], arguments);
        c.context = c.context || b.getService(a), c.moduleID = a;
        return this.getCommunication().subscribe(c)
    }, this.unsubscribe = function() {
        var c = d(["eventType", "context", "context", "instance", "DOMElement"], arguments);
        return c.context = c.context || b.getService(a), c.moduleID = a, b.logger.log({
            name: a,
            msg: "Unsubscribe to the event: " + c.eventType,
            type: "signals"
        }), this.getCommunication().unsubscribe(c)
    }, this.addEventProxy = function(c) {
        return b.logger.log({
            name: a,
            msg: "Set event proxy between elements",
            data: c,
            type: "signals"
        }), b.getService("DOMCommunication").EventProxy.addEventProxy(c)
    }, this.removeEventProxy = function(c) {
        return b.logger.log({
            name: a,
            msg: "Remove event proxy between elements",
            data: c,
            type: "signals"
        }), b.getService("DOMCommunication").EventProxy.removeEventProxy(c)
    }, this.fireInAllApps = function(a, c) {
        b.instanceManager.notifyAll(a, c)
    }, this.getOption = function(c) {
        for (var d = "[object String]" == Object.prototype.toString.call(c) ? [c] : c, e = {}, f = 0; f < d.length; f++) e[d[f]] = b.options[d[f]].value;
        var g = 1 == d.length ? e[d[0]] : e;
        return b.logger.log({
            name: a,
            msg: 'Get the "' + d + '" option with value -> ',
            data: g,
            type: "options"
        }), g
    }, this.isOriginalContainerTextBased = function() {
        return this.getOption("isTextBasedContainer")
    }, this.getDefaultOption = function(a) {
        for (var c = "[object String]" == Object.prototype.toString.call(a) ? [a] : a, d = {}, e = 0; e < c.length; e++) d[c[e]] = b.options[c[e]].defaultValue;
        return 1 == c.length ? d[c[0]] : d
    }, this.setOption = function(c, d) {
        c in b.options && (b.options[c].value = d, b.options[c].storable && this.Utils.indexOf(this.getOption("options-to-restore"), c) > -1 && (b.logger.log({
            name: a,
            msg: 'Set the "' + c + '" option with value -> ',
            data: d,
            type: "options"
        }), this.DataStorage.setData(this.getOption("uid") + "_" + c, d)))
    }, this.addDeferredFunction = function(a, c) {
        b.getService("Deferred").register(a, c)
    }, this.removeAllDeferredFunctions = function() {
        b.getService("Deferred").unregisterAll()
    }, this.setFocused = function(a) {
        return b.options.focused.value = a
    }, this.getFocused = function() {
        return b.options.focused.value
    }, this.setContainer = function(a) {
        return b.options.container.value = a
    }, this.removeMarkupFromString = function(a) {
        var b = this,
            c = document.createElement("div"),
            d = b.getOption("misspelled_word_node"),
            e = b.getOption("data_attribute_name"),
            f = b.getOption("problem_grammar_node"),
            g = b.getOption("problem_grammar_data_attribute");
        c.innerHTML = a;
        for (var h = b.DOM.findNodeChildren(c, d, e), i = b.DOM.findNodeChildren(c, f, g); h.length > 0;) {
            for (var j = h.shift(), k = document.createDocumentFragment(); j.childNodes.length > 0;) k.appendChild(j.childNodes.item(0));
            j.parentNode.insertBefore(k, j), j.parentNode.removeChild(j)
        }
        for (; i.length > 0;) {
            for (var l = i.shift(), k = document.createDocumentFragment(); l.childNodes.length > 0;) k.appendChild(l.childNodes.item(0));
            l.parentNode.insertBefore(k, l), l.parentNode.removeChild(l)
        }
        return c.innerHTML
    }, this.getProblemNodeFromSelection = function(a) {
        var b, c, d, e, f, g, h, i, j, k, l = this.getSelection(),
            m = l.isBackwards(),
            n = l.rangeCount() ? l.getRangeAt(0) : null,
            o = n ? n.collapsed() : !0,
            p = l.anchorNode();
        switch (a) {
            case "scayt":
                i = this.getOption("misspelled_word_node"), j = this.getOption("data_attribute_name"), k = this.getOption("misspelled_word_class");
                break;
            case "grayt":
                i = this.getOption("problem_grammar_node"), j = this.getOption("problem_grammar_data_attribute"), k = this.getOption("problem_grammar_class")
        }
        if (h = this.Utils.isEqualNode(p, j) ? p : this.DOM.findNodeParents(p, i, j)[0], !h && !o) {
            b = this.Utils.removeSpecialCharacters(n.toString()), b = m ? b.split("").reverse().join("") : b, c = n.getNodes(), c = m ? c.reverse() : c;
            for (var q = 0, r = c.length; r > q; q++) if (d = c[q], 1 === d.nodeType && this.UILib.hasClass(d, k)) {
                e = this.UILib.attr(d, j), e = m ? e.split("").reverse().join("") : e, f = e.length >= b.length && 0 === e.indexOf(b), g = e.length < b.length && 0 === b.indexOf(e), (f || g) && (h = d);
                break
            }
        }
        return h
    }, this.getScaytNodeFromSelection = function() {
        return this.getProblemNodeFromSelection("scayt")
    }, this.getGraytNodeFromSelection = function() {
        return this.getProblemNodeFromSelection("grayt")
    }, this.getScaytNodesInElement = function(a) {
        var b = a ? a : this.getOption("container"),
            c = "." + this.getOption("misspelled_word_class");
        return this.UILib.find(c, b)
    }, this.getGraytNodesInElement = function(a) {
        var b = a ? a : this.getOption("container"),
            c = "." + this.getOption("problem_grammar_class");
        return this.UILib.find(c, b)
    }, this.getSavedSelectionParentContainer = function(a) {
        var b = null,
            c = this.Utils.getCurrentDocument(this.getOption("documentContainer"));
        return a && a.rangeInfos[0] && (b = a.rangeInfos[0].collapsed ? this.getParentBlockElement(c.getElementById(a.rangeInfos[0].markerId)) : this.getOption("container")), b
    }, this.getParentBlockElement = function(a) {
        for (var b = this.getOption("blockElementsRegex"), c = this.getOption("container"); a !== c;) {
            if (-1 !== a.nodeName.search(b)) return a;
            a = a.parentNode
        }
        return a
    }, this.getPrevSymbol = function(a, b) {
        var c, d, e = this.createRange(),
            f = document.createElement("div");
        return e.setStart(a, 0), e.setEndBefore(b), c = e.cloneContents(), f.appendChild(c), d = f.textContent || f.innerText, d = this.Utils.removeSpecialCharacters(d), d[d.length - 1]
    }, this.getNextSymbol = function(a, b) {
        var c, d, e = this.createRange(),
            f = document.createElement("div");
        return e.setStartAfter(b), e.setEnd(a, a.childNodes.length), c = e.cloneContents(), f.appendChild(c), d = f.textContent || f.innerText, d = this.Utils.removeSpecialCharacters(d), d[0]
    }, this.isNodeContentBroken = function(a, b) {
        var c = a.getAttribute(b),
            d = a.textContent || a.innerText;
        return d = this.Utils.removeSpecialCharacters(d), c !== d
    }, this.getBrokenProblemNodes = function(a, b) {
        var c, d, e, f, g = this.getOption("focused"),
            h = this.getSelection(),
            i = this.getOption("wordBoundaryRegex"),
            j = this;
        switch (a) {
            case "scayt":
                f = this.getOption("data_attribute_name"), d = "getScaytNodesInElement";
                break;
            case "grayt":
                f = this.getOption("problem_grammar_data_attribute"), d = "getGraytNodesInElement"
        }
        return b ? c = b : g && (c = h.anchorNode()), c ? (c = this.getParentBlockElement(c), e = this[d](c), e = this.Utils.arrayFilter.call(e, function(a) {
            if (j.isNodeContentBroken(a, f)) return !0;
            var b = j.getPrevSymbol(c, a);
            if (b && !i.test(b)) return !0;
            var d = j.getNextSymbol(c, a);
            return d && !i.test(d) ? !0 : void 0
        })) : void 0
    }, this.getBrokenScaytNodes = function(a) {
        return this.getBrokenProblemNodes("scayt", a)
    }, this.getBrokenGraytNodes = function(a) {
        return this.getBrokenProblemNodes("grayt", a)
    }, this.isCaretInStartOfMisspelledWord = function() {
        var a, b, c, d = this.getSelection(),
            e = d.rangeCount() ? d.getRangeAt(0) : null,
            f = this.getOption("data_attribute_name"),
            g = this.getOption("container"),
            h = this.getOption("blockElementsRegex"),
            i = this.getOption("punctuationRegExp"),
            j = this.getOption("wordBoundaryRegex");
        if (!e || !e.collapsed()) return !1;
        if (a = this.getScaytNodeFromSelection()) return 0 === e.startOffset() ? a : !1;
        b = new this.Utils.Walker(e.startContainer(), e.startOffset(), !0, g);
        do {
            if (b.siblingNode && h.test(b.siblingNode.nodeName.toLowerCase())) break;
            if (this.Utils.isEqualNode(b.currentNode, f)) {
                a = b.currentNode;
                break
            }
            if (c = this.Utils.removePunctuation(b.textWalkedThrough, i), j.test(c)) break
        } while (b.getNext());
        return a
    }, this.isCaretInEndOfMisspelledWord = function() {
        var a, b, c, d, e, f = this.getSelection(),
            g = f.rangeCount() ? f.getRangeAt(0) : null,
            h = this.getOption("data_attribute_name"),
            i = this.getOption("container");
        if (!g || !g.collapsed()) return !1;
        if (a = this.getScaytNodeFromSelection()) {
            if (b = g.startContainer(), g.startOffset() === b.length && a.childNodes[a.childNodes.length - 1] === b) return !0
        } else {
            if (c = g.startContainer(), c.childNodes && c.childNodes.length > 0) {
                if (c = c.childNodes[g.startOffset()], !c) return !0
            } else if (0 !== g.startOffset()) return !1;
            d = new this.Utils.Walker(c, 0, !1, i);
            do
                if (this.Utils.isEqualNode(d.currentNode, h) && d.textWalkedThrough.length > 0) {
                    a = d.currentNode, a = a.childNodes.length ? a.childNodes[a.childNodes.length - 1] : a;
                    break
                }
            while (d.getNext());
            if (!a) return !1;
            if (e = this.createRange(), e.setStart(a, a.nodeValue.length), e.setEnd(c, 0), 0 === e.toString().length) return !0
        }
        return !1
    }, this.saveRange = function(c, d) {
        var e;
        return e = b.getService("RangeCreator").getRangeManager().saveRange(c, d), b.logger.log({
            name: a,
            msg: "Save the range",
            data: e,
            type: "range"
        }), e
    }, this.restoreRange = function(c, d) {
        var e;
        return c ? (e = b.getService("RangeCreator").getRangeManager().restoreRange(c, d), b.logger.log({
            name: a,
            msg: "Restore the range",
            data: e,
            type: "range"
        }), e) : void 0
    }
}, function(a) {
    "use strict";
    var b, c;
    c = function() {
        function a(a) {
            var b = a,
                c = Object.prototype.toString.call(a).slice(8, -1).toLowerCase();
            return a && "object" === c && "undefined" != typeof a.toArray && (b = a.toArray()), b
        }
        function b(a) {
            var b = [],
                c = Object.prototype.toString.call(a).slice(8, -1).toLowerCase();
            if (a && ("htmlcollection" === c || "nodelist" === c || "object" === c && "undefined" != typeof a.length && "undefined" != typeof a[0] && "undefined" == typeof a.nodeType)) {
                for (var d = 0; d < a.length; b.push(a[d]), d++);
                a = b
            }
            return SCAYT.jquip(a)
        }
        this.find = function(c, d) {
            var e;
            return e = "undefined" == typeof d ? b(c) : b(d).find(c), a(e)
        }, this.parent = function(c, d) {
            var e = b(c).parent(d);
            return a(e)
        }, this.parents = function(c, d) {
            var e = b(c).parents(d);
            return a(e)
        }, this.is = function(c, d) {
            var e = b(c).is(d);
            return a(e)
        }, this.each = function(a, c) {
            b(a).each(c)
        }, this.filter = function(c, d) {
            var e = b(c).filter(d);
            return a(e)
        }, this.create = function(b) {
            return a(SCAYT.jquip(b))
        }, this.remove = function(b) {
            return a(SCAYT.jquip(b).remove())
        }, this.appendTo = function(b, c) {
            return a(SCAYT.jquip(b).appendTo(SCAYT.jquip(c)))
        }, this.prependTo = function(b, c) {
            return a(SCAYT.jquip(b).prependTo(SCAYT.jquip(c)))
        }, this.append = function(b, c) {
            return a(SCAYT.jquip(b).append(SCAYT.jquip(c)))
        }, this.prepend = function(b, c) {
            return a(SCAYT.jquip(b).prepend(SCAYT.jquip(c)))
        }, this.insertAfter = function(b, c) {
            return a(SCAYT.jquip(b).insertAfter(SCAYT.jquip(c)))
        }, this.insertBefore = function(b, c) {
            return a(SCAYT.jquip(b).insertBefore(SCAYT.jquip(c)))
        }, this.attr = function(b, c, d) {
            return a(SCAYT.jquip(b).attr(c, d))
        }, this.removeAttr = function(b, c) {
            return a(SCAYT.jquip(b).removeAttr(c))
        }, this.addClass = function(b, c) {
            return a(SCAYT.jquip(b).addClass(c))
        }, this.removeClass = function(b, c) {
            return a(SCAYT.jquip(b).removeClass(c))
        }, this.hasClass = function(b, c) {
            return a(SCAYT.jquip(b).hasClass(c))
        }, this.css = function(b, c) {
            return a(SCAYT.jquip(b).css(c))
        }, this.show = function(b) {
            return a(SCAYT.jquip(b).show())
        }, this.hide = function(b) {
            return a(SCAYT.jquip(b).hide())
        }, this.html = function(b, c) {
            return a(SCAYT.jquip(b).html(c))
        }, this.val = function(b, c) {
            return a(SCAYT.jquip(b).val(c))
        }, this.text = function(b, c) {
            return a(SCAYT.jquip(b).text(c))
        }, this.empty = function(b) {
            return a(SCAYT.jquip(b).empty())
        }, this.domReady = function(a) {
            SCAYT.jquip(a)
        }, this.on = function(a, b, c, d) {
            SCAYT.jquip(b).on(a, c, d)
        }, this.off = function(a, b, c, d) {
            SCAYT.jquip(b).off(a, c, d)
        }, this.one = function(a, b, c) {
            SCAYT.jquip(b).one(a, c)
        }, this.trigger = function(a, b) {
            return SCAYT.jquip(b).trigger(a)
        }, this.getEventTarget = function(a) {
            var b = a.target;
            return b || (b = a.srcElement || document), 3 === b.nodeType && (b = b.parentNode), b
        }, this.cancelEvent = function(a) {
            return SCAYT.jquip.cancelEvent(a)
        }, this.preventDefault = function(a) {
            a && (a.preventDefault ? a.preventDefault() : a.returnValue = !1)
        }, this.defaultPrevented = function(a) {
            return a ? void 0 !== a.defaultPrevented ? a.defaultPrevented : a.returnValue === !1 ? !0 : !1 : a.defaultPrevented
        }, this.stopPropagation = function(a) {
            a && (a.cancelBubble = !0, a.stopPropagation && a.stopPropagation())
        }, this.stopImmediatePropagation = function(a) {
            a && (a.isImmediatePropagationStopped = function() {
                return !0
            }, this.stopPropagation(a), a.stopImmediatePropagation && a.stopImmediatePropagation())
        }, this.focus = function() {
            var b, c = [];
            return Array.prototype.push.apply(c, arguments), b = SCAYT.jquip(c.shift()), a(b.focus.apply(b, c))
        }, this.blur = function() {
            var b, c = [];
            return Array.prototype.push.apply(c, arguments), b = SCAYT.jquip(c.shift()), a(b.blur.apply(b, c))
        }, this.contextmenu = function() {
            var b, c = [];
            return Array.prototype.push.apply(c, arguments), b = SCAYT.jquip(c.shift()), a(b.contextmenu.apply(b, c))
        }, this.proxy = function(a, b) {
            return SCAYT.jquip.proxy(a, b)
        }, this.width = function(a, b) {
            return SCAYT.jquip(a).width(b)
        }, this.height = function(a, b) {
            return SCAYT.jquip(a).height(b)
        }, this.outerWidth = function(a, b) {
            return SCAYT.jquip(a).outerWidth(b)
        }, this.outerHeight = function(a, b) {
            return SCAYT.jquip(a).outerHeight(b)
        }, this.scrollLeft = function(a, b) {
            return SCAYT.jquip(a).scrollLeft(b)
        }, this.scrollTop = function(a, b) {
            return SCAYT.jquip(a).scrollTop(b)
        }, this.offset = function(a) {
            return SCAYT.jquip(a).offset()
        }, this.extend = function() {
            return SCAYT.jquip.extend.apply(SCAYT.jquip, arguments)
        }
    }, b = new c;
    var d = {
        find: function() {
            return b.find.apply(b, arguments)
        },
        parent: function() {
            return b.parent.apply(b, arguments)
        },
        parents: function() {
            return b.parents.apply(b, arguments)
        },
        is: function() {
            return b.is.apply(b, arguments)
        },
        each: function() {
            b.each.apply(b, arguments)
        },
        filter: function() {
            return b.filter.apply(b, arguments)
        },
        create: function() {
            return b.create.apply(b, arguments)
        },
        remove: function() {
            return b.remove.apply(b, arguments)
        },
        appendTo: function() {
            return b.appendTo.apply(b, arguments)
        },
        prependTo: function() {
            return b.prependTo.apply(b, arguments)
        },
        append: function() {
            return b.append.apply(b, arguments)
        },
        prepend: function() {
            return b.prepend.apply(b, arguments)
        },
        insertAfter: function() {
            return b.insertAfter.apply(b, arguments)
        },
        insertBefore: function() {
            return b.insertBefore.apply(b, arguments)
        },
        attr: function() {
            return b.attr.apply(b, arguments)
        },
        removeAttr: function() {
            return b.removeAttr.apply(b, arguments)
        },
        addClass: function() {
            return b.addClass.apply(b, arguments)
        },
        removeClass: function() {
            return b.removeClass.apply(b, arguments)
        },
        hasClass: function() {
            return b.hasClass.apply(b, arguments)
        },
        css: function() {
            return b.css.apply(b, arguments)
        },
        show: function() {
            return b.show.apply(b, arguments)
        },
        hide: function() {
            return b.hide.apply(b, arguments)
        },
        html: function() {
            return b.html.apply(b, arguments)
        },
        val: function() {
            return b.val.apply(b, arguments)
        },
        text: function() {
            return b.text.apply(b, arguments)
        },
        empty: function() {
            return b.empty.apply(b, arguments)
        },
        domReady: function(a) {
            b.domReady(a)
        },
        on: function(a, c, d, e) {
            void 0 === e && (e = d, d = void 0), b.on.apply(b, [a, c, d || e, e])
        },
        off: function(c, d, e, f) {
            a.Utils;
            void 0 === f && "function" == typeof e && (f = e, e = void 0), b.off.apply(b, [c, d, e, f])
        },
        one: function() {
            b.one.apply(b, arguments)
        },
        trigger: function(a, c, d) {
            return d ? (c = this.find(c)[0], c.dispatchEvent ? c.dispatchEvent(d) : c.fireEvent ? c.fireEvent("on" + a, d) : void 0) : b.trigger.apply(b, arguments)
        },
        getEventTarget: function() {
            return b.getEventTarget.apply(b, arguments)
        },
        cancelEvent: function() {
            return b.cancelEvent.apply(b, arguments)
        },
        createEvent: function() {
            var a;
            return document.createEvent ? a = document.createEvent("Event") : document.createEventObject && (a = document.createEventObject()), a
        },
        preventDefault: function(a) {
            b.preventDefault(a)
        },
        stopPropagation: function(a) {
            b.stopPropagation(a)
        },
        stopImmediatePropagation: function(a) {
            b.stopImmediatePropagation(a)
        },
        isDefaultPrevented: function(a) {
            return b.defaultPrevented(a)
        },
        focus: function() {
            return b.focus.apply(b, arguments)
        },
        blur: function() {
            return b.blur.apply(b, arguments)
        },
        contextmenu: function() {
            return b.contextmenu.apply(b, arguments)
        },
        proxy: function() {
            return b.proxy.apply(b, arguments)
        },
        width: function() {
            return b.width.apply(b, arguments)
        },
        height: function() {
            return b.height.apply(b, arguments)
        },
        outerWidth: function() {
            return b.outerWidth.apply(b, arguments)
        },
        outerHeight: function() {
            return b.outerHeight.apply(b, arguments)
        },
        scrollLeft: function() {
            return b.scrollLeft.apply(b, arguments)
        },
        scrollTop: function() {
            return b.scrollTop.apply(b, arguments)
        },
        offset: function() {
            return b.offset.apply(b, arguments)
        },
        extend: function() {
            return b.extend.apply(b, arguments)
        },
        setPosition: function(a, b, c) {
            "number" == typeof b && "number" == typeof c && this.css(a, {
                left: b,
                top: c
            })
        }
    };
    a.UILib = d
}(SCAYT.prototype), function(a) {
    "use strict";
    if (!a.instanceManager) {
        var b = [],
            c = {
                add: function(a) {
                    b.push(a)
                },
                remove: function(a) {
                    for (var c = 0; c < b.length; c++) b[c].getOption("uid") === a && b.splice(c, 1)
                },
                notifyAll: function(a, c) {
                    for (var d = 0; d < b.length; d++) b[d].fire(a, c)
                },
                getUniqueId: function(c) {
                    var d = a.Utils.hashCode(location.href);
                    return c.id ? c.id + "_" + d : "scayt_" + b.length + "_" + d
                },
                getScaytControlById: function(a) {
                    for (var c = null, d = 0, e = b.length; e > d; d++) if (b[d].originalElementId && b[d].originalElementId === a) {
                        c = b[d].instance;
                        break
                    }
                    return c
                }
            };
        a.instanceManager = c
    }
}(SCAYT.prototype), function(a) {
    "use strict";
    var b = a.UILib,
        c = {
            query: function(a, c) {
                return b.find(c, a)
            },
            findNodeChildren: function(a, c, d) {
                return b.find(c + "[" + d + "]", a)
            },
            findNodeParents: function(a, c, d) {
                return b.parents(a, c + "[" + d + "]")
            },
            insertAfter: function(a, c) {
                return b.insertAfter(a, c)
            }
        };
    a.DOM = c
}(SCAYT.prototype), function(a) {
    "use strict";
    var b = {
        lang: {},
        loadLocalization: function(a, b) {
            var c = b.getOption("detectLocalizationLanguage"),
                d = b.getDefaultOption("localization"),
                e = b.Utils.getLocationInfo(b.getOption("basePath"));
            c = c && d === a, c && (a = this.detect(a, b), b.setOption("localization", a)), b.IO.loadScript(new b.IO.URL({
                protocol: e.protocol,
                host: e.host,
                port: e.port,
                path: e.pathname + b.getOption("localizationPath") + a + "/local.js"
            }))
        },
        getLocal: function(a, b) {
            return this.lang[b] && this.lang[b][a] ? this.lang[b][a] : a
        },
        detect: function(a, b) {
            var c = b.getOption("localizationList"),
                d = navigator.userLanguage || navigator.language || a,
                e = b.getOption("supportLocale"),
                f = d.toLowerCase().match(/([a-z]+)(?:-([a-z]+))?/),
                g = f[1],
                h = f[2],
                i = b.Utils.indexOf;
            return e && i(c, g + "-" + h) > 0 ? g = g + "-" + h : i(c, g) < 0 && (g = a), g
        }
    };
    a.Localization = b
}(SCAYT.prototype), function(a) {
    "use strict";
    var b = {
        Walker: function(a, b, c, d) {
            var e = c ? "nextSibling" : "previousSibling",
                f = 3 === a.nodeType ? c ? a.nodeValue.substr(b, a.nodeValue.length) : a.nodeValue.substr(0, b) : "";
            this.textWalkedThrough = f, this.currentNode = a, this.previousNode = null, this.siblingNode = null, this.getNext = function() {
                if (this.currentNode.childNodes.length > 0 && this.previousNode && this.currentNode.childNodes[c * (this.currentNode.childNodes.length - 1)] !== this.previousNode ? (this.previousNode = this.currentNode, this.currentNode = this.currentNode.childNodes[!c * (this.currentNode.childNodes.length - 1)], this.siblingNode = null) : this.currentNode.childNodes.length > 0 && !this.previousNode && this.currentNode.childNodes[b - !c] ? (this.previousNode = this.currentNode, this.currentNode = this.currentNode.childNodes[b - !c], this.siblingNode = null) : this.currentNode[e] ? (this.previousNode = this.currentNode, this.currentNode = this.currentNode[e], this.siblingNode = this.currentNode) : (this.previousNode = this.currentNode, this.currentNode = this.currentNode.parentNode, this.siblingNode = null), this.currentNode) switch (this.currentNode.nodeType) {
                    case 1:
                        this.currentNode === d && (this.currentNode = null);
                        break;
                    case 3:
                        if (/\n+\s*/.test(this.currentNode.nodeValue)) break;
                        c ? this.textWalkedThrough += this.currentNode.nodeValue : this.textWalkedThrough = this.currentNode.nodeValue + this.textWalkedThrough
                }
                return this.currentNode
            }, this.reset = function() {
                this.textWalkedThrough = f, this.currentNode = a, this.previousNode = null, this.siblingNode = null
            }
        },
        findFirstNodeWithString: function(a, b) {
            for (var c = [a], d = c.shift(); d;) {
                switch (d.nodeType) {
                    case 3:
                        if (-1 !== d.nodeValue.indexOf(b)) return d;
                        break;
                    case 1:
                        for (var e = 0; e < d.childNodes.length; e++) c.splice(e, 0, d.childNodes[e]);
                        c.length > d.childNodes.length && c.splice(e, 0, document.createTextNode(" "))
                }
                d = c.shift()
            }
            return null
        },
        isEqualNode: function(a, b) {
            var c = !1;
            return a && (c = a.getAttribute && a.getAttribute(b) ? !0 : !1), c
        },
        removePunctuation: function(a, b) {
            return a = a.replace(new RegExp(String.fromCharCode(160), "g"), " "), a = a.replace(new RegExp("[" + b.source + "]", "g"), " "), a = a.replace(/([\.\-\']{2,})/g, "#$1#").replace(/#[\.\-\']|[\.\-\']#/g, " "), a = a.replace(new RegExp(" [-'.]|[-'.] ", "g"), "  "), a = a.replace(new RegExp("^[-'.]|[-'.]$", "g"), " "), a = a.replace(/[\r\n(\r\n)\<\>\\\/\=\"]/g, " ")
        },
        replaceSpecialCharacters: function(a) {
            return a = a.replace(new RegExp(String.fromCharCode(160), "g"), " ")
        },
        removeSpecialCharacters: function(a) {
            return a = a.replace(new RegExp(String.fromCharCode(65279), "g"), ""), a = a.replace(new RegExp(String.fromCharCode(8203), "g"), "")
        },
        removeFillingCharacter: function(a) {
            return a = a.replace(new RegExp(String.fromCharCode(8204), "g"), "")
        },
        objectIsEmpty: function(a) {
            for (var b in a) if (a.hasOwnProperty(b)) return !1;
            return !0
        },
        removeGlobal: function(a, b) {
            b = b || window;
            try {
                delete b.variable
            } catch (c) {
                b.variable = void 0
            }
        },
        sortRangesForMurkup: function(a, b) {
            var c = b.compareBoundaryPoints(0, a);
            return c
        },
        getCurrentDocument: function(a) {
            var b;
            return b = "iframe" == a.nodeName.toLowerCase() ? a.contentWindow.document : document
        },
        getWindowByDocument: function(a) {
            return "defaultView" in a ? a.defaultView : a.parentWindow
        },
        fixRangeBoundaryPoints: function(a) {
            var b = {
                startNode: a.startContainer(),
                endNode: a.endContainer(),
                startOffset: a.startOffset(),
                endOffset: a.endOffset()
            };
            if (b.startNode.parentNode != b.endNode.parentNode) {
                var c = a.commonAncestorContainer(),
                    d = b.startNode;
                if (0 === b.startOffset) {
                    for (; d.parentNode != c && d.parentNode.firstChild == d;) d = d.parentNode;
                    b.startBeforeNode = d
                }
                if (b.startNode = d, d = b.endNode, d.length == b.endOffset) {
                    for (; d.parentNode != c && d.parentNode.lastChild == d;) d = d.parentNode;
                    b.endAfterNode = d
                }
            }
            return a.setStart(b.startNode, b.startOffset), a.setEnd(b.endNode, b.endOffset), b.startBeforeNode && a.setStartBefore(b.startBeforeNode), b.endAfterNode && a.setEndAfter(b.endAfterNode), a
        },
        arrayFilter: function(a) {
            var b = this.length;
            if ("function" != typeof a) throw new TypeError;
            for (var c = [], d = arguments[1], e = 0; b > e; e++) if (e in this) {
                var f = this[e];
                a.call(d, f, e, this) && c.push(f)
            }
            return c
        },
        indexOf: function(a) {
            function b(a) {
                if (null == this) throw new TypeError;
                var b, c, d = Object(this),
                    e = d.length >>> 0;
                if (0 === e) return -1;
                if (b = 0, arguments.length > 1 && (b = Number(arguments[1]), b != b ? b = 0 : 0 != b && 1 / 0 != b && b != -1 / 0 && (b = (b > 0 || -1) * Math.floor(Math.abs(b)))), b >= e) return -1;
                for (c = b >= 0 ? b : Math.max(e - Math.abs(b), 0); e > c; c++) if (c in d && d[c] === a) return c;
                return -1
            }
            var c, d = Array.prototype.slice.apply(arguments);
            return d.shift(), c = "[object Array]" !== Object.prototype.toString.call(a) || Array.prototype.indexOf ? Array.prototype.indexOf.apply(a, d) : b.apply(a, d)
        },
        arrayUnique: function(a, b) {
            for (var c = a.concat(), b = b ||
                function(a, b) {
                    return a === b
                }, d = 0; d < c.length; ++d) for (var e = d + 1; e < c.length; ++e) b(c[d], c[e]) && c.splice(e--, 1);
            return c
        },
        argumentsToArray: function(a) {
            for (var b = a.length, c = new Array(b), d = 0; b > d; d += 1) c[d] = a[d];
            return c
        },
        zipArraysToObject: function(a, b) {
            for (var c = {}, d = 0; d < a.length; d += 1) c[a[d]] = b[d];
            return c
        },
        diffArrays: function(a, b) {
            for (var c = [], d = b.length, e = 0; d > e; e++) this.indexOf(a, b[e]) < 0 && c.push(b[e]);
            return c
        },
        inArray: function(a, b) {
            for (var c = 0; c < a.length; c++) if (a[c] === b) return !0;
            return !1
        },
        extendOptions: function(a, b) {
            for (var c in b) a[c] = b[c]
        },
        getUrl: function(a, b) {
            return -1 == a.indexOf(":/") && 0 !== a.indexOf("/") && (a = b + a), a
        },
        is: function(a, b) {
            var c = Object.prototype.toString.call(a).slice(8, -1);
            return void 0 !== a && null !== a && c === b
        },
        getLocationInfo: function(a) {
            var b = document.createElement("a");
            return b.href = a, {
                protocol: b.protocol.replace(/:/, ""),
                host: b.host.split(":")[0],
                port: "0" == b.port ? "80" : b.port,
                pathname: b.pathname.replace(/^\//, "")
            }
        },
        getKeys: Object.keys ||
        function(a) {
            var b, c = [];
            for (b in a) a.hasOwnProperty(b) && c.push(b);
            return c
        },
        assign: Object.assign ||
        function(a) {
            if (void 0 === a || null === a) throw new TypeError("Cannot convert undefined or null to object");
            for (var b = Object(a), c = 1; c < arguments.length; c++) {
                var d = arguments[c];
                if (void 0 !== d && null !== d) for (var e in d) d.hasOwnProperty(e) && (b[e] = d[e])
            }
            return b
        },
        bind: function(a, b) {
            return function() {
                return a.apply(b, arguments)
            }
        },
        browser: function() {
            var a = navigator.userAgent.toLowerCase(),
                b = a.match(/edge[ \/](\d+.?\d*)/),
                c = a.indexOf("trident/") > -1,
                d = !(!b && !c),
                e = window.opera,
                f = {
                    ie: d,
                    edge: !! b,
                    opera: !! e && e.version,
                    webkit: !d && a.indexOf(" applewebkit/") > -1,
                    air: a.indexOf(" adobeair/") > -1,
                    mac: a.indexOf("macintosh") > -1,
                    quirks: "BackCompat" == document.compatMode && (!document.documentMode || document.documentMode < 10),
                    mobile: a.indexOf("mobile") > -1,
                    iOS: /(ipad|iphone|ipod)/.test(a)
                };
            f.gecko = "Gecko" == navigator.product && !f.webkit && !f.opera && !f.ie, f.webkit && (a.indexOf("chrome") > -1 ? f.chrome = !0 : f.safari = !0);
            var g = 0;
            if (f.ie && (g = b ? parseFloat(b[1]) : f.quirks || !document.documentMode ? parseFloat(a.match(/msie (\d+)/)[1]) : document.documentMode), f.gecko) {
                var h = a.match(/rv:([\d\.]+)/);
                h && (h = h[1].split("."), g = 1e4 * h[0] + 100 * (h[1] || 0) + 1 * (h[2] || 0))
            }
            return f.air && (g = parseFloat(a.match(/ adobeair\/(\d+)/)[1])), f.webkit && (g = parseFloat(a.match(/ applewebkit\/(\d+)/)[1])), f.version = g, f
        }(),
        trim: function(a) {
            function b(a) {
                var b = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
                return b.lastIndex = 0, a.replace(b, "")
            }
            var c = "";
            return c = a.trim ? a.trim() : b(a)
        },
        extend: function(a, b) {
            var c, d;
            if (a = a || Object, c = function() {}, c.prototype = a.prototype, "function" != typeof b && (d = b, b = function() {}), b.prototype = new c, b.parent = a.prototype, b.prototype.constructor = b, d && null !== d && "object" == typeof d) for (var e in d) d.hasOwnProperty(e) && (b.prototype[e] = d[e]);
            return b
        },
        hashCode: function(a) {
            var b, c = 0;
            if (0 === a.length) return c;
            for (var d = 0, e = a.length; e > d; d++) b = a.charCodeAt(d), c = (c << 5) - c + b, c &= c;
            return c
        },
        trunc: function(a, b) {
            return a.length > b ? a.substr(0, b) + "&hellip;" : a
        },
        copyStyles: function(b, c) {
            var d = null,
                e = a.UILib,
                f = {};
            if (d = document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(b, null) : b.currentStyle, !d) return null;
            for (var g in d) f[d[g]] = d[d[g]];
            e.css(c, f)
        }
    };
    a.Utils = b
}(SCAYT.prototype), function(a) {
    "use strict";
    var b = window.console || {},
        c = window.JSON || {},
        d = ["log", "warn", "info", "debug"],
        e = a.Utils.browser;
    c.stringify = c.stringify ||
        function() {
            return arguments
        };
    for (var f = 0; f < d.length; f++) b[d[f]] = b[d[f]] ||
        function() {};
    var g = !1,
        h = {
            isON: function(a) {
                a = a || !1, g = a ? !0 : /scaytDebug\b/.test(location.hash)
            },
            isIE: e.ie,
            log: function(a) {
                var d = a || {},
                    e = void 0;
                g && (e = "object" == typeof d ? [d.name, ":: " + d.msg, d.data] : [d], this.isIE ? (e = [d.name, ":: " + d.msg, c.stringify(d.data, null, "")], e = e.join(" "), b.log(e)) : b.log.apply(b, e))
            },
            console: b
        };
    a.logger = h
}(SCAYT.prototype), function(a) {
    "use strict";
    var b = a.UILib,
        c = a.Utils,
        d = a.logger.console,
        e = !1,
        f = [],
        g = {
            XMLHttpRequest: "undefined" != typeof XMLHttpRequest ? XMLHttpRequest : null,
            XDomainRequest: "undefined" != typeof XDomainRequest ? XDomainRequest : null,
            URL: function(a) {
                a = a || {};
                var b = "",
                    d = a.protocol || "http",
                    e = a.host || "localhost",
                    f = a.port || "80",
                    g = a.path || "",
                    h = {};
                this.addParameter = function(a, b) {
                    return a && b && (h[a] = b), this
                }, this.getParameter = function(a) {
                    return h[a]
                }, this.joinUrl = function() {
                    var a = "";
                    return a += d + "://", a += e, a += "80" == f ? "/" : ":" + f + "/", a += g.replace(/^\/*/, "")
                }, this.joinRequestParams = function() {
                    var a = "";
                    if (c.getKeys(h).length) {
                        for (var b in h) a += b + "=" + encodeURIComponent(h[b]) + "&";
                        return a.slice(0, -1)
                    }
                    return ""
                }, this.build = function() {
                    var a = this.joinRequestParams();
                    return b += this.joinUrl(), b += a ? "?" : "", b += a
                }
            },
            AJAX: function(a) {
                var b = {},
                    h = JSON.parse ||
                        function() {
                            return arguments
                        };
                if (e) {
                    for (var i = 0; i < f.length; i++) f[i].success && a.onSuccess(f[i].success), f[i].error && a.onError(f[i].error);
                    return {
                        finished: !0
                    }
                }
                return b.params = {
                    url: a.url.joinUrl(),
                    data: a.url.joinRequestParams(),
                    onSuccess: a.onSuccess,
                    onError: a.onError
                }, "1:tLBmI3-7rr3J1-GMEFA1-mIewo-hynTZ1-PV38I1-uEXCy2-Rn81L-gXuG4-NUNri4-5q9Q34-Jd" === a.url.getParameter("customerid") && (b.params.url += "?app=demo_free"), b.request = new g.XMLHttpRequest, null !== g.XDomainRequest ? b.request = new g.XDomainRequest : "withCredentials" in b.request ? b.request.withCredentials = !1 : d.warn("Cors is not supported by this browser!"), b.request.onload = function() {
                    var a = b.request.responseText,
                        c = b.request.status;
                    if (b.success = !0, 200 !== c) b.params.onError && b.params.onError({});
                    else {
                        try {
                            a = h(a)
                        } catch (e) {
                            d.warn("CORS response parsing error: " + e)
                        }
                        a && a.error ? (a.message && d.warn(a.message), b.params.onError && b.params.onError(a)) : b.params.onSuccess && b.params.onSuccess(a)
                    }
                }, b.request.onerror = function() {
                    b.error = !0, b.params.onError && b.params.onError({})
                }, b.request.onabort = function() {
                    b.error = !0, b.params.onError && b.params.onError({})
                }, b.request.open("POST", b.params.url, !0), c.browser.ie && 9 === c.browser.version ? setTimeout(function() {
                    b.request.send(b.params.data)
                }, 500) : b.request.send(b.params.data), b
            },
            JSONP: function(a) {
                var b = "callback" + Math.random().toString(20).substr(2, 9),
                    c = "SCAYT.prototype.IO.";
                if (e) {
                    for (var d = 0; d < f.length; d++) f[d].success && a.onSuccess(f[d].success), f[d].error && a.onError(f[d].error);
                    return b
                }
                return a.url.addParameter("callback", c + b), new g.Script({
                    url: a.url.build(),
                    id: b,
                    callbackName: b,
                    onSuccess: a.onSuccess,
                    onError: a.onError
                })
            },
            Script: function(a) {
                a = a || {};
                var c, e = this,
                    f = function() {
                        SCAYT.prototype.IO[a.callbackName] = function(a) {
                            c = a
                        }
                    },
                    g = function() {
                        delete SCAYT.prototype.IO[a.callbackName]
                    },
                    h = function() {
                        g(), e.removeScript()
                    };
                a.callbackName && f();
                var i = document.createElement("script");
                i.type = "text/javascript", i.id = a.id ? a.id : "", i.src = a.url ? a.url : "", i.charset = "UTF-8", i.onload = function() {
                    this.success || (this.success = !0, a.callbackName ? (c && c.error ? (c.message && d.warn(c.message), a.onError && a.onError(c)) : a.onSuccess && a.onSuccess(c), h()) : a.onSuccess && a.onSuccess())
                }, i.onerror = function() {
                    this.error = !0, a.onError && a.onError({}), a.callbackName && h()
                }, i.onreadystatechange = function() {
                    var a = this;
                    ("complete" === this.readyState || "loaded" === this.readyState) && setTimeout(function() {
                        a.onload()
                    }, 0)
                }, b.appendTo(i, "head"), this.getScript = function() {
                    return i
                }, this.removeScript = function() {
                    b.remove(i), i = null
                }
            },
            get: function(a, b, c) {
                return g.request({
                    url: a,
                    onSuccess: b,
                    onError: c
                })
            },
            loadScript: function(a, b, c) {
                var d = g.loadScript.cache ? g.loadScript.cache : g.loadScript.cache = {};
                if (a = a.build(), !d.hasOwnProperty(a)) {
                    d[a] = !0;
                    var e = new g.Script({
                        url: a,
                        onSuccess: b,
                        onError: c
                    });
                    return e
                }
            },
            ioMockStart: function(a) {
                e = !0, f = a ? a : f
            },
            ioMockEnd: function() {
                e = !1
            }
        };
    g.request = g.AJAX, a.IO = g
}(SCAYT.prototype), function(a) {
    "use strict";
    var b = {},
        c = function f(a, c) {
            var d = /\W/.test(a) ? new Function("obj", "var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('" + a.replace(/[\r\t\n]/g, " ").split("<%").join("	").replace(/((^|%>)[^\t]*)'/g, "$1\r").replace(/\t=(.*?)%>/g, "',$1,'").split("	").join("');").split("%>").join("p.push('").split("\r").join("\\'") + "');}return p.join('');") : b[a] = b[a] || f(document.getElementById(a).innerHTML.replace(/\r\n/, ""));
            return c ? d(c) : d
        },
        d = a.UILib,
        e = {
            create: function(a, b) {
                var c;
                document.getElementById(a) || (c = document.createElement("script"), c.type = "text/html", c.id = a, c.text = b, d.appendTo(c, "body"))
            },
            remove: function(a) {
                d.remove("body #" + a), delete b[a]
            },
            render: function(a, b) {
                return c(a, b)
            }
        };
    a.Template = e
}(SCAYT.prototype), function(a) {
    "use strict";
    var b = {
            separator: "<$>",
            getDataType: function(a) {
                var b;
                return b = "undefined" == typeof a ? "undefined" : null === a ? "null" : Object.prototype.toString.call(a).slice(8, -1)
            },
            convertDataToString: function(a) {
                var b, c = this.getDataType(a).toLowerCase();
                return b = c + this.separator + a
            },
            restoreDataFromString: function(a) {
                var b, c, d = a;
                if (a = this.backCompatibility(a), "string" == typeof a) switch (c = a.indexOf(this.separator), b = a.substring(0, c), d = a.substring(c + this.separator.length), b) {
                    case "boolean":
                        d = "true" === d;
                        break;
                    case "number":
                        d = parseFloat(d);
                        break;
                    case "array":
                        d = "" === d ? [] : d.split(",");
                        break;
                    case "null":
                        d = null;
                        break;
                    case "undefined":
                        d = void 0
                }
                return d
            },
            backCompatibility: function(a) {
                var b, c, d = a;
                return "string" == typeof a && (c = a.indexOf(this.separator), 0 > c && (b = parseFloat(a), isNaN(b) && ("[" === a[0] && "]" === a[a.length - 1] ? (a = a.replace("[", ""), a = a.replace("]", ""), b = "" === a ? [] : a.split(",")) : b = "true" === a || "false" === a ? "true" === a : a), d = this.convertDataToString(b))), d
            }
        },
        c = {
            get: function(a) {
                var c = b.restoreDataFromString(window.localStorage.getItem(a));
                return c
            },
            set: function(a, c) {
                var d = b.convertDataToString(c);
                window.localStorage.setItem(a, d)
            },
            del: function(a) {
                window.localStorage.removeItem(a)
            },
            clear: function() {
                window.localStorage.clear()
            }
        },
        d = {
            expiration: function() {
                return 31622400
            }(),
            get: function(a) {
                var c = b.restoreDataFromString(this.getCookie(a));
                return c
            },
            set: function(a, c) {
                var d = b.convertDataToString(c);
                this.setCookie(a, d, {
                    expires: this.expiration
                })
            },
            del: function(a) {
                this.deleteCookie(a)
            },
            getCookie: function(a) {
                "string" != typeof a && (a = "");
                var b = document.cookie.match(new RegExp("(?:^|; )" + a.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1") + "=([^;]*)"));
                return b ? decodeURIComponent(b[1]) : void 0
            },
            setCookie: function(a, b, c) {
                c = c || {};
                var d = c.expires;
                if ("number" == typeof d && d) {
                    var e = new Date;
                    e.setTime(e.getTime() + 1e3 * d), d = c.expires = e
                }
                d && d.toUTCString && (c.expires = d.toUTCString()), b = encodeURIComponent(b);
                var f = a + "=" + b;
                for (var g in c) {
                    var h = c[g];
                    f += "; " + g, h !== !0 && (f += "=" + h)
                }
                document.cookie = f
            },
            deleteCookie: function(a) {
                this.setCookie(a, null, {
                    expires: -1
                })
            },
            clear: function() {
                for (var a = document.cookie.split(";"), b = 0; b < a.length; b++) {
                    var c = a[b],
                        d = c.indexOf("="),
                        e = d > -1 ? c.substr(0, d) : c;
                    this.deleteCookie(e)
                }
            }
        },
        e = function() {
            try {
                var a = "localStorage" in window && null !== window.localStorage;
                return a ? (window.localStorage.setItem("_localStorageSupported", 1), window.localStorage.removeItem("_localStorageSupported"), !0) : !1
            } catch (b) {
                return !1
            }
        },
        f = e() ? c : d,
        g = {
            getData: function(a) {
                return f.get(a)
            },
            setData: function(a, b) {
                f.set(a, b)
            },
            deleteData: function(a) {
                f.del(a)
            },
            clear: function() {
                f.clear()
            }
        };
    a.DataStorage = g
}(SCAYT.prototype), function(a) {
    "use strict";
    var b, c = function(a, c) {
        this.name = a, this.sandbox = c, b = c.Utils
    };
    c.prototype = {
        init: function() {
            var a = this;
            this.sandbox.subscribe({
                eventType: "allModulesReady",
                handler: function() {
                    a.documentContainer = a.sandbox.getOption("documentContainer")
                }
            }), this.documentContainer = this.sandbox.getOption("documentContainer"), this.blockElementsRegex = this.sandbox.getOption("blockElementsRegex"), this.ignoreElementsRegex = this.sandbox.getOption("ignoreElementsRegex");
            var b = this.sandbox.getOption("punctuationRegExp");
            this.libAdapter = c.RangyAdapter, this.rangyOptions = {
                wordRegex: /[^\s]+/g,
                tokenizer: function(a, c) {
                    function d(b, c, d) {
                        for (var e = a.slice(b, c), f = {
                            isWord: d,
                            chars: e,
                            toString: function() {
                                return e.join("")
                            }
                        }, g = 0, h = e.length; h > g; ++g) e[g].token = f;
                        j.push(f)
                    }
                    var e, f, g, h = a.join(""),
                        i = 0,
                        j = [];
                    for (h = SCAYT.prototype.Utils.removePunctuation(h, b); g = c.wordRegex.exec(h);) e = g.index, f = e + g[0].length, e > i && d(i, e, !1), d(e, f, !0), i = f;
                    return i < a.length && d(i, a.length, !1), j
                }
            }
        },
        createRange: function() {
            return new c.Range(new this.libAdapter(this.documentContainer, this.blockElementsRegex, this.ignoreElementsRegex, this.rangyOptions))
        },
        getSelection: function(a) {
            return new c.Selection(new this.libAdapter(this.documentContainer, this.blockElementsRegex, this.ignoreElementsRegex, this.rangyOptions), a)
        },
        getSelectionManager: function() {
            return new c.SelectionManager(new this.libAdapter(this.documentContainer, this.blockElementsRegex, this.ignoreElementsRegex, this.rangyOptions))
        },
        getRangeManager: function() {
            return new c.RangeManager(new this.libAdapter(this.documentContainer, this.blockElementsRegex, this.ignoreElementsRegex, this.rangyOptions))
        },
        comparisonType: {
            START_TO_START: 0,
            START_TO_END: 1,
            END_TO_START: 3,
            END_TO_END: 2
        }
    }, c.Range = function(a) {
        var b = a.range;
        b.createRange(), this.collapsed = function() {
            return b.collapsed()
        }, this.commonAncestorContainer = function() {
            return b.commonAncestorContainer()
        }, this.endContainer = function() {
            return b.endContainer()
        }, this.endOffset = function() {
            return b.endOffset()
        }, this.startContainer = function() {
            return b.startContainer()
        }, this.startOffset = function() {
            return b.startOffset()
        }, this.setStart = function(a, c) {
            return b.setStart(a, c)
        }, this.setEnd = function(a, c) {
            return b.setEnd(a, c)
        }, this.setStartBefore = function(a) {
            return b.setStartBefore(a)
        }, this.setStartAfter = function(a) {
            return b.setStartAfter(a)
        }, this.setEndBefore = function(a) {
            return b.setEndBefore(a)
        }, this.setEndAfter = function(a) {
            return b.setEndAfter(a)
        }, this.selectNode = function(a) {
            return b.selectNode(a)
        }, this.selectNodeContents = function(a) {
            return b.selectNodeContents(a)
        }, this.collapse = function(a) {
            return b.collapse(a)
        }, this.cloneContents = function() {
            return b.cloneContents()
        }, this.deleteContents = function() {
            return b.deleteContents()
        }, this.extractContents = function() {
            return b.extractContents()
        }, this.insertNode = function(a) {
            return b.insertNode(a)
        }, this.surroundContents = function(a) {
            return b.surroundContents(a)
        }, this.compareBoundaryPoints = function(a, b) {
            return b.compareBoundaryPoints(a, b)
        }, this.cloneRange = function() {
            return b.cloneRange()
        }, this.detach = function() {
            return b.detach()
        }, this.toString = function() {
            return b.toString()
        }, this.createContextualFragment = function(a) {
            return b.createContextualFragment(a)
        }, this.move = function(a, c, d) {
            return b.move(a, c, d)
        }, this.expand = function(a, c) {
            return b.expand(a, c)
        }, this.getNodes = function() {
            return b.getNodes()
        }, this.moveEnd = function(a, c, d) {
            return b.moveEnd(a, c, d)
        }, this.moveStart = function(a, c, d) {
            return b.moveStart(a, c, d)
        }, this.getBookmark = function(a) {
            return b.getBookmark(a)
        }, this.moveToBookmark = function(a) {
            return b.moveToBookmark(a)
        }, this.containsRange = function(a) {
            return b.containsRange(a._getRangyRange())
        }, this._getRangyRange = function() {
            return b._getRangyRange()
        }
    }, c.RangeManager = function(a) {
        var b = a.rangeManager;
        return {
            saveRange: function(a, c) {
                return b.saveRange(a, c)
            },
            restoreRange: function(a, c) {
                return b.restoreRange(a, c)
            }
        }
    }, c.RangeManager.prototype = {}, c.Selection = function(a, b) {
        var c = a.selection;
        c.getSelection(b), this.rangeCount = function() {
            return c.rangeCount()
        }, this.getRangeAt = function(a) {
            return c.getRangeAt(a)
        }, this.removeAllRanges = function() {
            return c.removeAllRanges()
        }, this.addRange = function(a) {
            return c.addRange(a)
        }, this.anchorNode = function() {
            return c.anchorNode()
        }, this.anchorOffset = function() {
            return c.anchorOffset()
        }, this.focusNode = function() {
            return c.focusNode()
        }, this.focusOffset = function() {
            return c.focusOffset()
        }, this.move = function(a, b, d) {
            return c.move(a, b, d)
        }, this.expand = function(a, b) {
            return c.expand(a, b)
        }, this.isBackwards = function() {
            return c.isBackwards()
        }
    }, c.SelectionManager = function(a) {
        var b = a.selectionManager;
        return {
            saveSelection: function() {
                return b.saveSelection()
            },
            restoreSelection: function(a) {
                return b.restoreSelection(a)
            },
            removeMarkers: function(a) {
                return b.removeMarkers(a)
            }
        }
    }, c.SelectionManager.prototype = {}, c.RangyAdapter = function(a, d, e, f) {
        var g = SCAYT.prototype.UILib;
        c.Lib = c.Lib || SCAYT.rangy || window.rangy, c.Lib.initialized === !1 && c.Lib.init();
        var h, i = null,
            j = {
                range: {
                    createRange: function() {
                        return h = c.Lib.createRange(a)
                    },
                    collapsed: function() {
                        return h.collapsed
                    },
                    commonAncestorContainer: function() {
                        return h.commonAncestorContainer
                    },
                    endContainer: function() {
                        return h.endContainer
                    },
                    endOffset: function() {
                        return h.endOffset
                    },
                    startContainer: function() {
                        return h.startContainer
                    },
                    startOffset: function() {
                        return h.startOffset
                    },
                    setStart: function(a, b) {
                        return h.setStart(a, b)
                    },
                    setEnd: function(a, b) {
                        return h.setEnd(a, b)
                    },
                    setStartBefore: function(a) {
                        return h.setStartBefore(a)
                    },
                    setStartAfter: function(a) {
                        return h.setStartAfter(a)
                    },
                    setEndBefore: function(a) {
                        return h.setEndBefore(a)
                    },
                    setEndAfter: function(a) {
                        return h.setEndAfter(a)
                    },
                    selectNode: function(a) {
                        return h.selectNode(a)
                    },
                    selectNodeContents: function(a) {
                        return h.selectNodeContents(a)
                    },
                    collapse: function(a) {
                        return h.collapse(a)
                    },
                    cloneContents: function() {
                        return h.cloneContents()
                    },
                    deleteContents: function() {
                        return h.deleteContents()
                    },
                    extractContents: function() {
                        return h.extractContents()
                    },
                    insertNode: function(a) {
                        return h.insertNode(a)
                    },
                    surroundContents: function(a) {
                        return h.surroundContents(a)
                    },
                    compareBoundaryPoints: function(b, d) {
                        var e = c.Lib.createRange(a);
                        return e.setStart(d.startContainer(), d.startOffset()), e.setEnd(d.endContainer(), d.endOffset()), h.compareBoundaryPoints(b, e)
                    },
                    cloneRange: function() {
                        var b = new c.Range(new c.RangyAdapter(a, d, e, f));
                        return b.setStart(this.startContainer(), this.startOffset()), b.setEnd(this.endContainer(), this.endOffset()), b
                    },
                    detach: function() {
                        return h.detach()
                    },
                    toString: function() {
                        for (var a = "", b = h.cloneContents(), c = [b], f = c.shift(); f;) {
                            switch (f.nodeType) {
                                case 3:
                                    a += f.nodeValue;
                                    break;
                                case 1:
                                case 11:
                                    if (f.nodeName.match(e)) a += " ";
                                    else {
                                        for (var g = 0; g < f.childNodes.length; g++) c.splice(g, 0, f.childNodes[g]);
                                        f.nodeName.match(d) && (c.length > f.childNodes.length && c.splice(g, 0, document.createTextNode(" ")), a.length > 0 && " " != a[a.length - 1] && c.splice(0, 0, document.createTextNode(" ")))
                                    }
                            }
                            f = c.shift()
                        }
                        return a
                    },
                    createContextualFragment: function(a) {
                        return h.createContextualFragment(a)
                    },
                    move: function(a, b, c) {
                        return h.move(a, b, "word" !== a || c ? c : f)
                    },
                    expand: function(a, b) {
                        return h.expand(a, "word" !== a || b ? b : f)
                    },
                    getNodes: function() {
                        return h.getNodes()
                    },
                    moveEnd: function(a, b, c) {
                        return h.moveEnd(a, b, "word" !== a || c ? c : f)
                    },
                    moveStart: function(a, b, c) {
                        return h.moveStart(a, b, "word" !== a || c ? c : f)
                    },
                    getBookmark: function(a) {
                        return h.getBookmark(a)
                    },
                    moveToBookmark: function(b) {
                        var g = !1;
                        return b && (h.moveToBookmark(b), g = new c.Range(new c.RangyAdapter(a, d, e, f)), g.setStart(h.startContainer, h.startOffset), g.setEnd(h.endContainer, h.endOffset)), g
                    },
                    containsRange: function(a) {
                        return h.containsRange(a)
                    },
                    _getRangyRange: function() {
                        return h
                    }
                },
                selection: {
                    getSelection: function(b) {
                        var d = function() {
                            i = "boolean" == typeof b && b || "iframe" !== a.nodeName.toLowerCase() ? c.Lib.getSelection() : c.Lib.getSelection(a)
                        };
                        null !== i && this.detach();
                        try {
                            d()
                        } catch (e) {
                            this.detach(), d()
                        }
                        return i
                    },
                    rangeCount: function() {
                        return i.rangeCount
                    },
                    getRangeAt: function(b) {
                        var g = i.getRangeAt(b),
                            h = new c.Range(new c.RangyAdapter(a, d, e, f));
                        return h.setStart(g.startContainer, g.startOffset), h.setEnd(g.endContainer, g.endOffset), h
                    },
                    removeAllRanges: function() {
                        return i.removeAllRanges()
                    },
                    addRange: function(b) {
                        var d = c.Lib.createRange(a);
                        return d.setStart(b.startContainer(), b.startOffset()), d.setEnd(b.endContainer(), b.endOffset()), i.addRange(d)
                    },
                    anchorNode: function() {
                        return i.anchorNode
                    },
                    anchorOffset: function() {
                        return i.anchorOffset
                    },
                    focusNode: function() {
                        return i.focusNode
                    },
                    focusOffset: function() {
                        return i.focusOffset
                    },
                    move: function(a, b, c) {
                        return i.move(a, b, c)
                    },
                    expand: function(a, b) {
                        return i.expand(a, b)
                    },
                    detach: function() {
                        c.Lib.Selection.detachAll()
                    },
                    isBackwards: function() {
                        return i.isBackwards()
                    }
                },
                selectionManager: {
                    saveSelection: function() {
                        var d;
                        try {
                            g.is(a, ":visible") && (d = "iframe" == a.nodeName.toLowerCase() ? c.Lib.saveSelection(a) : c.Lib.saveSelection(), d.doc = b.getCurrentDocument(a))
                        } catch (e) {}
                        return d
                    },
                    restoreSelection: function(a) {
                        function b(a) {
                            for (var b = [], d = a.length, e = d - 1; e >= 0; e--) b[e] = c.Lib.restoreRange(a[e], !1);
                            return b
                        }
                        if (!a.restored) {
                            var d = a.rangeInfos,
                                e = j.selection.getSelection(a.win),
                                f = b(d),
                                g = d.length;
                            1 == g && c.Lib.features.selectionHasExtend && d[0].backward ? (e.removeAllRanges(), e.addRange(f[0], !0)) : e.setRanges(f), a.restored = !0
                        }
                        return a.restored
                    },
                    removeMarkers: function(a) {
                        c.Lib.removeMarkers(a)
                    }
                },
                rangeManager: {
                    saveRange: function(b, d) {
                        var e, f;
                        return f = c.Lib.createRange(a), f.setStart(b.startContainer(), b.startOffset()), b.collapsed() || f.setEnd(b.endContainer(), b.endOffset()), e = c.Lib.saveRange(f, d)
                    },
                    restoreRange: function(b, g) {
                        var h, i = !1;
                        return b && (h = c.Lib.restoreRange(b, g), i = new c.Range(new c.RangyAdapter(a, d, e, f)), i.setStart(h.startContainer, h.startOffset), i.setEnd(h.endContainer, h.endOffset)), i
                    }
                }
            };
        return j
    }, c.TestAdapter = function() {
        c.Lib = c.Lib || window.TestLib, SCAYT.Utils.removeGlobal(window.TestLib);
        return {
            createRange: function() {
                return c.Lib.createRange()
            },
            selectNodeContents: function(a) {
                return c.Lib.selectNodeContents(a)
            },
            collapse: function(a) {
                return c.Lib.collapse(a)
            },
            createContextualFragment: function(a) {
                return c.Lib.createContextualFragment(a)
            },
            insertNode: function(a) {
                return c.Lib.insertNode(a)
            }
        }
    }, a.RangeCreator = c
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b, this.container = this.sandbox.getOption("container"), this.documentContainer = this.sandbox.getOption("focusContainer"), this.isCustomerIdFree = this.sandbox.Utils.inArray([this.sandbox.getDefaultOption("customer_id"), "1:qj8W21-rSO4B4-mNSem1-qi1mq1-fgmuL1-Qfpgn4-wZUMl3-V3oaC-DcLr92-mPqvU2-TwpSC4-LHb"], this.sandbox.getOption("customer_id"))
    };
    b.prototype = {
        init: function() {
            var a = this,
                b = this.sandbox.getOption("isServiceHostDefault");
            this.sandbox.subscribe({
                eventType: "allModulesReady",
                handler: function() {
                    a.removeBindings(), a.documentContainer = a.sandbox.getOption("focusContainer"), a.container = this.sandbox.getOption("container"), a.addBindings()
                }
            }), this.addBindings(), b && this.getBanner()
        },
        destroy: function() {
            this.removeBindings()
        },
        getBanner: function() {
            var a = this.sandbox,
                b = this;
            this.sandbox.IO.get(new a.IO.URL({
                protocol: a.getOption("service_protocol"),
                host: a.getOption("service_host"),
                port: a.getOption("service_port"),
                path: a.getOption("service_path")
            }).addParameter("cmd", "getbanner").addParameter("customerid", a.getOption("customer_id")).addParameter("format", "json"), function(c) {
                c.banner ? a.setOption("isPaidVersion", !1) : a.setOption("isPaidVersion", !0), a.fire("subscriptionTypeChecked", {
                    subscriptionType: b.isCustomerIdFree ? "free" : "license"
                })
            }, function() {})
        },
        addBindings: function() {
            this.sandbox.subscribe({
                eventType: "focus",
                element: this.documentContainer,
                handler: this.focusHandler
            }), this.sandbox.subscribe({
                eventType: "blur",
                element: this.documentContainer,
                handler: this.blurHandler
            }), this.sandbox.subscribe({
                eventType: "mousedown",
                element: this.container,
                handler: this.mouseDownHandler
            }), this.sandbox.subscribe({
                eventType: "mouseup",
                element: this.container,
                handler: this.mouseUpHandler
            }), this.sandbox.subscribe({
                eventType: "keydown",
                element: this.container,
                handler: this.keydownHandler,
                priority: 2e3,
                context: this
            }), this.sandbox.subscribe({
                eventType: "keyup",
                element: this.container,
                handler: this.keyupHandler,
                priority: 2e3,
                context: this
            })
        },
        removeBindings: function() {
            this.sandbox.unsubscribe({
                eventType: "focus",
                element: this.documentContainer,
                handler: this.focusHandler
            }), this.sandbox.unsubscribe({
                eventType: "blur",
                element: this.documentContainer,
                handler: this.blurHandler
            }), this.sandbox.unsubscribe({
                eventType: "mousedown",
                element: this.container,
                handler: this.mouseDownHandler
            }), this.sandbox.unsubscribe({
                eventType: "mouseup",
                element: this.container,
                handler: this.mouseUpHandler
            }), this.sandbox.unsubscribe({
                eventType: "keydown",
                element: this.container,
                handler: this.keydownHandler,
                context: this
            }), this.sandbox.unsubscribe({
                eventType: "keyup",
                element: this.container,
                handler: this.keyupHandler,
                context: this
            })
        },
        focusHandler: function() {
            this.sandbox.setFocused(!0)
        },
        blurHandler: function() {
            this.sandbox.setFocused(!1)
        },
        mouseDownHandler: function() {
            this.sandbox.setOption("leftMouseButtonPressed", !0)
        },
        mouseUpHandler: function() {
            this.sandbox.setOption("leftMouseButtonPressed", !1)
        },
        keydownHandler: function(a) {
            switch (a.keyCode) {
                case 46:
                    this.sandbox.setOption("deleteKeyButtonPressed", !0);
                    break;
                case 8:
                    this.sandbox.setOption("backspaceKeyButtonPressed", !0);
                    break;
                case 32:
                    this.sandbox.setOption("spaceKeyButtonPressed", !0);
                    break;
                case 13:
                    this.sandbox.setOption("enterKeyButtonPressed", !0)
            }
        },
        keyupHandler: function(a) {
            switch (a.keyCode) {
                case 46:
                    this.sandbox.setOption("deleteKeyButtonPressed", !1);
                    break;
                case 8:
                    this.sandbox.setOption("backspaceKeyButtonPressed", !1);
                    break;
                case 32:
                    this.sandbox.setOption("spaceKeyButtonPressed", !1);
                    break;
                case 13:
                    this.sandbox.setOption("enterKeyButtonPressed", !1)
            }
        }
    }, a.StateController = b
}(SCAYT), function(a) {
    "use strict";
    var b, c = function(a, d) {
        this.name = a, this.sandbox = d, b = d.Utils, this.events = {}, c.Signal = c.Signal || SCAYT.signals.Signal
    };
    c.prototype = {
        init: function() {
            var a = ["appStarted", "startSpellCheck", "moduleStarted", "selectionIsChanged", "saveSelection", "restoreSelection", "collectWords", "wordsCollected", "misspelledWordsFound", "replaceWord", "sentWordsCount", "getWordsLimit", "freeze", "startGrammarCheck", "collectSentences", "sentencesCollected", "getGrammarSuggestionsList", "problemPhrasesFound", "markupPhrase", "ignorePhrase", "ignoreAllPhrases", "replacePhrase", "removeMarkupFromPhrases", "removeGrammarMarkupInSelectionNode", "updateSentencesCache", "graytStateChanged", "markupWords", "getSuggestionsList", "suggestionListSend", "ignoreWord", "ignoreAllWords", "removeMarkupInDocument", "removeMarkupFromWords", "removeMarkupInSelectionNode", "taskEnded", "spellCheckStarted", "spellCheckEnded", "beforemanualcontrolblur", "subscriptionTypeChecked", "showBanner", "hideBanner", "openWSCwindow", "documentReadyForSpelling", "suggestionListRendered", "commitOptions", "getUserDictionaryName", "getUserDictionary", "createUserDictionary", "renameUserDictionary", "restoreUserDictionary", "removeUserDictionary", "disconnectFromUserDictionary", "setUserDictionaryName", "addWordToUserDictionary", "deleteWordFromUserDictionary", "userDictionaryChanged", "userDictionaryStateChanged", "userDictionaryStateRestored", "userDictionaryAction", "keydownCharLengthOnFakeElement", "cutProcessed", "copyProcessed", "pasteProcessed", "afterPaste", "beforeContextMenuShow", "contextMenuHide", "dialogDefinition", "onLoad", "onShow", "onHide", "onClose", "onSubmit", "onCancel", "afterTabShow", "appReady", "calculateWords", "dictionaryChanged", "defaultTextchanged", "backgroundColorChanged", "allModulesReady", "moduleReady", "markupedNode", "removedMarkupInContainer", "removeMarkup", "setShortcuts", "removeShortcuts", "undo", "redo", "executeUndo", "executeRedo", "checkUndoRedoPosibility", "undoRedoPosibility", "dropProcessed", "crossContainerDrop", "afterDrop"];
            this.addEvents(a)
        },
        addEvents: function(a) {
            for (var b = 0; b < a.length; b += 1) {
                var c = a[b];
                this.events[c] = this.createSignal()
            }
        },
        createSignal: function() {
            return new c.Signal
        },
        fire: function(a) {
            a = a || {};
            for (var b, d, e = (a.moduleID, a.data || {}), f = a.eventType.split(","), g = "", h = [], i = 0; i < f.length; i++) g = this.sandbox.Utils.trim(f[i]), b = this.events[g], d = new c.Event(g, e, b), b.dispatch(d), h.push(d.aggregateEventData());
            return h.length > 1 ? h : h[0]
        },
        subscribe: function(a) {
            a = a || {};
            for (var b = (a.moduleID, a.eventType, a.handler), c = a.context, d = a.priority || 0, e = a.eventType.split(","), f = "", g = 0; g < e.length; g++) f = this.sandbox.Utils.trim(e[g]), this.events[f].add(b, c, d)
        },
        unsubscribe: function(a) {
            a = a || {};
            for (var b, c, d = (a.moduleID, a.eventType, a.context), e = a.eventType.split(","), f = 0, g = 0; g < e.length; g++) if (c = this.sandbox.Utils.trim(e[g]), b = this.events[c], d) for (; b._bindings[f];) b._bindings[f].context === d ? b.remove(b._bindings[f]._listener, d) : f++;
            else b.removeAll()
        }
    }, c.Event = function(a, c, d) {
        b.assign(this, c), this._type = a, this._eventData = [], this._signal = d, this._propagationStopped = !1, this._defaultPrevented = !1, this._immediatePropagationStopped = !1
    }, c.Event.prototype = {
        constructor: c.Event,
        setReturnedData: function(a) {
            if (!b.is(a, "Object")) throw new TypeError("data is not a object");
            this._eventData.push(a)
        },
        preventDefault: function() {
            this._defaultPrevented = !0
        },
        isDefaultPrevented: function() {
            return this._defaultPrevented
        },
        stopPropagation: function() {
            this._propagationStopped = !0
        },
        stopImmediatePropagation: function() {
            this._immediatePropagationStopped = !0, this._signal.halt()
        },
        isEventDataEmpty: function() {
            return this._eventData.length > 0 ? !1 : !0
        },
        isPropagationStopped: function() {
            return this._propagationStopped
        },
        aggregateEventData: function(a) {
            var c = this._eventData,
                d = {};
            a = a || b.assign;
            for (var e = 0; e < c.length; e += 1) a(d, c[e]);
            return d
        }
    }, a.Communication = c
}(SCAYT), function(a) {
    "use strict";
    var b, c, d, e = function(a, e) {
        this.name = a, this.sandbox = e, this.decorator = !0, this.decoratorFor = "Communication", b = this.UILib = this.sandbox.FullUILib, c = this.Utils = this.sandbox.Utils, d = this.logger = this.sandbox.console, this.events = {}
    };
    e.prototype = {
        constructor: e,
        init: function() {
            this.eventsNames = ["click", "dblclick", "contextmenu", "mousedown", "mouseup", "mouseout", "mousemove", "mouseover", "mouseenter", "mouseleave", "focus", "blur", "keydown", "keypress", "keyup", "cut", "copy", "beforepaste", "paste", "drop", "drag", "dragover", "dragstart", "dragend", "dragenter", "dragleave", "change", "resize", "orientationchange", "select", "compositionstart", "compositionend", "selectionchange", "touchstart", "touchmove", "touchend"], this.EventProxy = new e.EventProxy(this)
        },
        destroy: function() {
            this.wrapMethod("unsubscribe")({
                eventType: this.eventsNames.join(", ")
            }), this.EventProxy.removeAllEventProxy()
        },
        decorate: function(a) {
            this.communication = a, this.addEvents(this.eventsNames), this.communication.addEvents(this.eventsNames);
            var b = {
                fire: this.wrapMethod("fire"),
                subscribe: this.wrapMethod("subscribe"),
                unsubscribe: this.wrapMethod("unsubscribe")
            };
            for (var c in this.communication) b[c] = b[c] ? b[c] : this.communication[c];
            return b
        },
        addEvents: function(a) {
            for (var b = 0; b < a.length; b += 1) {
                var c = a[b];
                this.events[c] = new e.UISignal(c, this.communication, this.name)
            }
        },
        checkOnEventSupport: function(a) {
            return !(!a || !a.addEventListener && !a.attachEvent)
        },
        validateListener: function(a, b) {
            if ("function" != typeof a) throw new Error("listener is a required param of {fn}() and should be a Function.".replace("{fn}", b));
            return a
        },
        setEventData: function(a, b) {
            var d = ["target", "srcElement", "currentTarget"];
            a.initEvent && a.initEvent(b.type, !0, !0);
            for (var e in b) if (-1 === c.indexOf(d, e) && "_" !== e[0] && "function" != typeof b[e]) try {
                a[e] = b[e]
            } catch (f) {}
            return a
        },
        checkEventTypes: function(a) {
            for (var b, c = 0; c < a.length; c += 1) if (b = this.sandbox.Utils.trim(a[c]), -1 !== this.sandbox.Utils.indexOf(this.eventsNames, b)) return !0;
            return !1
        },
        dispatchEvent: function(a, c, d) {
            var e = this.setEventData(b.createEvent(c), d);
            return !this.UILib.trigger(c, a, e)
        },
        fireBeforeEventsForContainer: function(a, b) {
            var c = this.sandbox.getOption("container"),
                d = this.sandbox.getOption("documentContainer"),
                e = (this.Utils.getCurrentDocument(d), "beforemanualcontrol");
            ("focus" === a && b.element !== c && document.activeElement === d || "blur" === a && b.element === c) && this.communication.fire({
                eventType: e + "blur"
            })
        },
        fire: function(a, d) {
            var e, f, g = d.element,
                h = this.events[a],
                i = ["click", "focus", "blur"],
                j = {};
            return -1 !== c.indexOf(i, a) ? (f = function(a) {
                e = b.isDefaultPrevented(a)
            }, b.on(a, g, f), this.fireBeforeEventsForContainer(a, d), g[a](), b.off(a, g, f)) : (d.data = d.data || {}, d.data.type || (d.data.type = a), e = this.dispatchEvent(g, a, d.data)), null === h.lastSystemFireResult ? j.defaultPrevented = e : (j = h.lastSystemFireResult, h.lastSystemFireResult = null), j
        },
        subscribe: function(a, b) {
            var c = this,
                d = c.events[a],
                f = {
                    element: b.element,
                    userContext: b.context,
                    userHandler: c.validateListener(b.handler, "subscribe")
                };
            d.addSubscription(f), b.userContext = b.context, b.context = f, b.handler = function(a) {
                if (a.constructor !== e.UIEventDecorator) {
                    if (void 0 === a.nativeEvent) return;
                    a = new e.UIEventDecorator(a)
                }
                a.currentTarget === this.element && this.userHandler.call(this.userContext, a)
            }, c.communication.subscribe(b)
        },
        unsubscribe: function(a, b) {
            function c(a, c) {
                f.removeSubscription(a, c), e.communication.unsubscribe(b)
            }
            for (var d, e = this, f = e.events[a], g = b.handler, h = b.element, i = f.subscribers.length - 1; i >= 0; i -= 1) d = f.subscribers[i], b.userContext = b.userContext || b.context, b.context = d, b.userContext && b.userContext !== d.userContext || (h ? d.element === h && (g ? (g = e.validateListener(b.handler, "unsubscribe"), g === d.userHandler && c(d, i)) : c(d, i)) : c(d, i), b.context = b.userContext)
        },
        prepareOption: function(a, b) {
            return b.element === this.sandbox.getOption("container") && "focus" === a && this.Utils.browser.gecko && this.sandbox.getOption("isIframe") === !0 && (b.element = this.sandbox.getOption("focusContainer"), b.eventType.split(",").length > 1 && d.warn("You can't call focus event with another events in one fire/subscribe method with another events. For this case focus event should be one in 'eventType'")), b
        },
        wrapMethod: function(a) {
            var b = this;
            return function(e) {
                var f, g, h, i = e.eventType.split(","),
                    j = [];
                if (b.checkEventTypes(i)) {
                    if (b.checkOnEventSupport(e.element) === !1 && "unsubscribe" !== a) return d.warn(e.eventType + " event/s defined in " + b.name + " module. For " + a + " DOM events you should set (HTMLElement | document) in method params"), null;
                    for (var k = 0; k < i.length; k += 1) f = b.Utils.trim(i[k]), e = b.prepareOption(f, e), h = e, i.length > 1 && (h = c.assign({}, e)), g = b[a].call(b, f, h), g && j.push(g);
                    return j.length > 1 ? j : j[0]
                }
                return b.communication[a](e)
            }
        }
    }, e.EventProxy = function(a) {
        this.DOMCommunication = a, this.proxyElements = []
    }, e.EventProxy.prototype = {
        constructor: e.EventProxy,
        addEventProxy: function(a) {
            var e = this.DOMCommunication;
            e.checkOnEventSupport(a.from) && e.checkOnEventSupport(a.to) || d.warn("for eventProxy you should provide 2 elements: 'from' and 'to'");
            var f = c.assign({}, a);
            f.eventsNames = a.eventsNames || e.eventsNames, f.handler = c.bind(function(a) {
                e.dispatchEvent(this.to, a.type, a)
            }, f), this.proxyElements.push(f);
            for (var g = 0; g < f.eventsNames.length; g += 1) b.on(f.eventsNames[g], f.from, f.handler)
        },
        removeAllEventProxy: function() {
            for (var a = 0; a < this.proxyElements.length; a += 1) this.removeEventProxy(this.proxyElements[a])
        },
        removeEventProxy: function(a) {
            for (var c, d = 0; d < this.proxyElements.length; d += 1) if (a.from === this.proxyElements[d].from && a.to === this.proxyElements[d].to) {
                c = this.proxyElements[d];
                break
            }
            for (d = 0; d < a.eventsNames.length; d += 1) b.off(c.eventsNames[d], c.from, c.handler)
        }
    }, e.UIEventDecorator = function(a) {
        this.eventPrototype = a.constructor.prototype, this.event = a, this.nativeEvent = a.nativeEvent;
        var d = b.isDefaultPrevented(this.nativeEvent);
        d && this.event.preventDefault(), a.setReturnedData({
            defaultPrevented: d
        });
        for (var e in this.nativeEvent) void 0 !== this.nativeEvent[e] && "function" != typeof this.nativeEvent[e] && (a[e] = this.nativeEvent[e]);
        for (e in this.constructor.prototype) a[e] = c.bind(this.constructor.prototype[e], this);
        return a.constructor = this.constructor, a.target = b.getEventTarget(this.nativeEvent), delete a.nativeEvent, a
    }, e.UIEventDecorator.prototype = {
        constructor: e.UIEventDecorator,
        preventDefault: function() {
            this.eventPrototype.isDefaultPrevented.call(this.event) === !1 && (b.preventDefault(this.nativeEvent), this.eventPrototype.setReturnedData.call(this.event, {
                defaultPrevented: !0
            }), this.eventPrototype.preventDefault.call(this.event))
        },
        stopPropagation: function() {
            b.stopPropagation(this.nativeEvent), this.eventPrototype.stopPropagation.call(this.event)
        },
        stopImmediatePropagation: function() {
            b.stopImmediatePropagation(this.nativeEvent), this.eventPrototype.stopImmediatePropagation.call(this.event)
        }
    }, e.UISignal = function(a, b, c) {
        var d = this;
        this.subscribers = [], this.registredElements = [], this.eventType = a, this.emmiter = b, this.moduleID = c, this.lastSystemFireResult = null, this.handler = function(a) {
            d.lastSystemFireResult = d.emmiter.fire({
                moduleID: d.moduleID,
                eventType: d.eventType,
                data: {
                    nativeEvent: a
                }
            })
        }
    }, e.UISignal.prototype = {
        constructor: e.UISignal,
        addSubscription: function(a) {
            this.subscribers.push(a), -1 === this.findElementIndex(a.element, this.registredElements) && this.registerElement(a.element)
        },
        removeSubscription: function(a, b) {
            var c = this.subscribers;
            if (!b) for (var d = 0; d < c.length; d += 1) c[d] === a && (b = d);
            c.splice(b, 1), -1 === this.findElementIndex(a.element, c) && this.unregisterElement(a.element)
        },
        registerElement: function(a) {
            var d, e = this;
            d = c.browser.ie && c.browser.version < 9 ?
                function(b) {
                    null === b && (b = c.getWindowByDocument(a.document).event), b.currentTarget = a, e.handler(b)
                } : this.handler, this.registredElements.push({
                element: a,
                handler: d
            }), b.on(this.eventType, a, d)
        },
        unregisterElement: function(a) {
            var c = this.findElementIndex(a, this.registredElements),
                d = this.registredElements[c];
            this.registredElements.splice(c, 1), b.off(this.eventType, a, d.handler)
        },
        findElementIndex: function(a, b) {
            for (var c = 0; c < b.length; c += 1) if (b[c].element === a) return c;
            return -1
        }
    }, a.DOMCommunication = e
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b, this.tasks = {}, this.taskCount = 0
    };
    b.prototype = {
        init: function() {
            this.sandbox.subscribe("taskEnded", function(a) {
                this.taskEndedHandler(a.taskName)
            }, this)
        },
        destroy: function() {
            this.unregisterAll()
        },
        taskEndedHandler: function(a) {
            this.unregister(a, !0), 0 === this.taskCount && this.sandbox.fire("spellCheckEnded", {})
        },
        register: function(a, c) {
            return 0 === this.taskCount && this.sandbox.fire("spellCheckStarted", {}), c.single && (this.unregister(a, !0), c.collection = ["single"]), this.tasks[a] ? this.tasks[a].extendCollection(c.collection) : (this.tasks[a] = new b.Task(a, c, this.sandbox), this.taskCount++, this.tasks[a].startTask()), this.tasks[a]
        },
        unregister: function(a, b) {
            this.tasks[a] && (this.tasks[a].timeout && (clearTimeout(this.tasks[a].timeout), this.tasks[a].timeout = null), this.taskCount--, !b && this.tasks[a].onUnregister && this.tasks[a].onUnregister.apply(this.tasks[a]), delete this.tasks[a])
        },
        unregisterAll: function() {
            for (var a in this.tasks) this.tasks.hasOwnProperty(a) && this.unregister(a)
        }
    }, b.Task = function(a, b, c) {
        function d(a) {
            return function() {
                a && a.apply(this, arguments), this.endTask()
            }
        }
        var e = this;
        b = b || {}, this.name = a, this.single = b.single || !1, this.collection = [].concat(b.collection || []), this.delay = b.delay || 0, this.partialItemsCount = b.partialItemsCount || 1, this.deferredFunction = d(b.deferredFunction), this.defferedFunctionArgs = b.defferedFunctionArgs || [], this.timeout = void 0, this.onUnregister = b.onUnregister, this.getPartialItems = function() {
            return this.collection.splice(0, this.partialItemsCount || 1)
        }, this.runDeferredFunction = function(a) {
            var b = this.deferredFunction.apply(this, [].concat([a], this.defferedFunctionArgs));
            return b
        }, this.extendCollection = function(a) {
            var b = [0, 0];
            b.push.apply(b, a), this.collection.splice.apply(this.collection, b)
        }, this.startTask = function() {
            this.timeout = setTimeout(function() {
                var a = e.getPartialItems();
                e.runDeferredFunction(a)
            }, this.delay)
        }, this.endTask = function() {
            this.timeout = null, this.collection.length > 0 ? this.startTask() : c.fire("taskEnded", {
                taskName: this.name
            })
        }
    }, a.Deferred = b
}(SCAYT), SCAYT.signals = function() {
    !
        function(a) {
            function b(a, b, c, d, e) {
                this._listener = b, this._isOnce = c, this.context = d, this._signal = a, this._priority = e || 0
            }
            function c(a, b) {
                if ("function" != typeof a) throw Error("listener is a required param of {fn}() and should be a Function.".replace("{fn}", b))
            }
            function d() {
                this._bindings = [], this._prevParams = null;
                var a = this;
                this.dispatch = function() {
                    d.prototype.dispatch.apply(a, arguments)
                }
            }
            b.prototype = {
                active: !0,
                params: null,
                execute: function(a) {
                    var b;
                    if (this.active && this._listener) {
                        a = this.params ? this.params.concat(a) : a;
                        try {
                            b = this._listener.apply(this.context, a)
                        } catch (c) {
                            setTimeout(function() {
                                throw c
                            }, 0)
                        } finally {
                            this._isOnce && this.detach()
                        }
                    }
                    return b
                },
                detach: function() {
                    return this.isBound() ? this._signal.remove(this._listener, this.context) : null
                },
                isBound: function() {
                    return !!this._signal && !! this._listener
                },
                isOnce: function() {
                    return this._isOnce
                },
                getListener: function() {
                    return this._listener
                },
                getSignal: function() {
                    return this._signal
                },
                _destroy: function() {
                    delete this._signal, delete this._listener, delete this.context
                },
                toString: function() {
                    return "[SignalBinding isOnce:" + this._isOnce + ", isBound:" + this.isBound() + ", active:" + this.active + "]"
                }
            }, d.prototype = {
                VERSION: "1.1.1",
                memorize: !1,
                _shouldPropagate: !0,
                active: !0,
                _registerListener: function(a, c, d, e) {
                    var f = this._indexOfListener(a, d);
                    if (-1 !== f) {
                        if (a = this._bindings[f], a.isOnce() !== c) throw Error("You cannot add" + (c ? "" : "Once") + "() then add" + (c ? "Once" : "") + "() the same listener without removing the relationship first.")
                    } else a = new b(this, a, c, d, e), this._addBinding(a);
                    return this.memorize && this._prevParams && a.execute(this._prevParams), a
                },
                _addBinding: function(a) {
                    var b = this._bindings.length;
                    do--b;
                    while (this._bindings[b] && a._priority <= this._bindings[b]._priority);
                    this._bindings.splice(b + 1, 0, a)
                },
                _indexOfListener: function(a, b) {
                    for (var c, d = this._bindings.length; d--;) if (c = this._bindings[d], c._listener === a && c.context === b) return d;
                    return -1
                },
                has: function(a, b) {
                    return -1 !== this._indexOfListener(a, b)
                },
                add: function(a, b, d) {
                    return c(a, "add"), this._registerListener(a, !1, b, d)
                },
                addOnce: function(a, b, d) {
                    return c(a, "addOnce"), this._registerListener(a, !0, b, d)
                },
                remove: function(a, b) {
                    c(a, "remove");
                    var d = this._indexOfListener(a, b);
                    return -1 !== d && (this._bindings[d]._destroy(), this._bindings.splice(d, 1)), a
                },
                removeAll: function() {
                    for (var a = this._bindings.length; a--;) this._bindings[a]._destroy();
                    this._bindings.length = 0
                },
                getNumListeners: function() {
                    return this._bindings.length
                },
                halt: function() {
                    this._shouldPropagate = !1
                },
                dispatch: function() {
                    if (this.active) {
                        for (var a = arguments.length, b = Array(a), c = 0; a > c; ++c) b[c] = arguments[c];
                        if (a = this._bindings.length, this.memorize && (this._prevParams = b), a) {
                            c = this._bindings.slice(), this._shouldPropagate = !0;
                            do a--;
                            while (c[a] && this._shouldPropagate && !1 !== c[a].execute(b))
                        }
                    }
                },
                forget: function() {
                    this._prevParams = null
                },
                dispose: function() {
                    this.removeAll(), delete this._bindings, delete this._prevParams
                },
                toString: function() {
                    return "[Signal active:" + this.active + " numListeners:" + this.getNumListeners() + "]"
                }
            }, d.Signal = d, a.signals = d
        }(this)
}, SCAYT.signals(), SCAYT.rangy = function() {
    !
        function(a) {
            function b(a, b) {
                var c = typeof a[b];
                return c == v || !(c != u || !a[b]) || "unknown" == c
            }
            function c(a, b) {
                return !(typeof a[b] != u || !a[b])
            }
            function d(a, b) {
                return typeof a[b] != w
            }
            function e(a) {
                return function(b, c) {
                    for (var d = c.length; d--;) if (!a(b, c[d])) return !1;
                    return !0
                }
            }
            function f(a) {
                return a && B(a, A) && D(a, z)
            }
            function g(a) {
                return c(a, "body") ? a.body : a.getElementsByTagName("body")[0]
            }
            function h(a) {
                typeof console != w && b(console, "log") && console.log(a)
            }
            function i(a, b) {
                G && b ? alert(a) : h(a)
            }
            function j(a) {
                I.initialized = !0, I.supported = !1, i("Rangy is not supported in this environment. Reason: " + a, I.config.alertOnFail)
            }
            function k(a) {
                i("Rangy warning: " + a, I.config.alertOnWarn)
            }
            function l(a) {
                return a.message || a.description || String(a)
            }
            function m() {
                if (G && !I.initialized) {
                    var a, c = !1,
                        d = !1;
                    b(document, "createRange") && (a = document.createRange(), B(a, y) && D(a, x) && (c = !0));
                    var e = g(document);
                    if (!e || "body" != e.nodeName.toLowerCase()) return void j("No body element found");
                    if (e && b(e, "createTextRange") && (a = e.createTextRange(), f(a) && (d = !0)), !c && !d) return void j("Neither Range nor TextRange are available");
                    I.initialized = !0, I.features = {
                        implementsDomRange: c,
                        implementsTextRange: d
                    };
                    var i, k;
                    for (var m in F)(i = F[m]) instanceof q && i.init(i, I);
                    for (var n = 0, o = L.length; o > n; ++n) try {
                        L[n](I)
                    } catch (p) {
                        k = "Rangy init listener threw an exception. Continuing. Detail: " + l(p), h(k)
                    }
                }
            }
            function n(a, b, c) {
                c && (a += " in module " + c.name), I.warn("DEPRECATED: " + a + " is deprecated. Please use " + b + " instead.")
            }
            function o(a, b, c, d) {
                a[b] = function() {
                    return n(b, c, d), a[c].apply(a, H.toArray(arguments))
                }
            }
            function p(a) {
                a = a || window, m();
                for (var b = 0, c = M.length; c > b; ++b) M[b](a)
            }
            function q(a, b, c) {
                this.name = a, this.dependencies = b, this.initialized = !1, this.supported = !1, this.initializer = c
            }
            function r(a, b, c) {
                var d = new q(a, b, function(b) {
                    if (!b.initialized) {
                        b.initialized = !0;
                        try {
                            c(I, b), b.supported = !0
                        } catch (d) {
                            var e = "Module '" + a + "' failed to load: " + l(d);
                            h(e), d.stack && h(d.stack)
                        }
                    }
                });
                return F[a] = d, d
            }
            function s() {}
            function t() {}
            var u = "object",
                v = "function",
                w = "undefined",
                x = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", "commonAncestorContainer"],
                y = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore", "setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents", "extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"],
                z = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"],
                A = ["collapse", "compareEndPoints", "duplicate", "moveToElementText", "parentElement", "select", "setEndPoint", "getBoundingClientRect"],
                B = e(b),
                C = e(c),
                D = e(d),
                E = [].forEach ?
                    function(a, b) {
                        a.forEach(b)
                    } : function(a, b) {
                    for (var c = 0, d = a.length; d > c; ++c) b(a[c], c)
                }, F = {}, G = typeof window != w && typeof document != w, H = {
                    isHostMethod: b,
                    isHostObject: c,
                    isHostProperty: d,
                    areHostMethods: B,
                    areHostObjects: C,
                    areHostProperties: D,
                    isTextRange: f,
                    getBody: g,
                    forEach: E
                }, I = {
                    version: "1.3.0",
                    initialized: !1,
                    isBrowser: G,
                    supported: !0,
                    util: H,
                    features: {},
                    modules: F,
                    config: {
                        alertOnFail: !1,
                        alertOnWarn: !1,
                        preferTextRange: !1,
                        autoInitialize: typeof rangyAutoInitialize == w ? !0 : rangyAutoInitialize
                    }
                };
            I.fail = j, I.warn = k;
            var J;
            ({}).hasOwnProperty ? (H.extend = J = function(a, b, c) {
                var d, e;
                for (var f in b) b.hasOwnProperty(f) && (d = a[f], e = b[f], c && null !== d && "object" == typeof d && null !== e && "object" == typeof e && J(d, e, !0), a[f] = e);
                return b.hasOwnProperty("toString") && (a.toString = b.toString), a
            }, H.createOptions = function(a, b) {
                var c = {};
                return J(c, b), a && J(c, a), c
            }) : j("hasOwnProperty not supported"), G || j("Rangy can only run in a browser"), function() {
                var a;
                if (G) {
                    var b = document.createElement("div");
                    b.appendChild(document.createElement("span"));
                    var c = [].slice;
                    try {
                        1 == c.call(b.childNodes, 0)[0].nodeType && (a = function(a) {
                            return c.call(a, 0)
                        })
                    } catch (d) {}
                }
                a || (a = function(a) {
                    for (var b = [], c = 0, d = a.length; d > c; ++c) b[c] = a[c];
                    return b
                }), H.toArray = a
            }();
            var K;
            G && (b(document, "addEventListener") ? K = function(a, b, c) {
                a.addEventListener(b, c, !1)
            } : b(document, "attachEvent") ? K = function(a, b, c) {
                a.attachEvent("on" + b, c)
            } : j("Document does not have required addEventListener or attachEvent method"), H.addListener = K);
            var L = [];
            H.deprecationNotice = n, H.createAliasForDeprecatedMethod = o, I.init = m, I.addInitListener = function(a) {
                I.initialized ? a(I) : L.push(a)
            };
            var M = [];
            I.addShimListener = function(a) {
                M.push(a)
            }, G && (I.shim = I.createMissingNativeApi = p, o(I, "createMissingNativeApi", "shim")), q.prototype = {
                init: function() {
                    for (var a, b, c = this.dependencies || [], d = 0, e = c.length; e > d; ++d) {
                        if (b = c[d], a = F[b], !(a && a instanceof q)) throw new Error("required module '" + b + "' not found");
                        if (a.init(), !a.supported) throw new Error("required module '" + b + "' not supported")
                    }
                    this.initializer(this)
                },
                fail: function(a) {
                    throw this.initialized = !0, this.supported = !1, new Error(a)
                },
                warn: function(a) {
                    I.warn("Module " + this.name + ": " + a)
                },
                deprecationNotice: function(a, b) {
                    I.warn("DEPRECATED: " + a + " in module " + this.name + " is deprecated. Please use " + b + " instead")
                },
                createError: function(a) {
                    return new Error("Error in Rangy " + this.name + " module: " + a)
                }
            }, I.createModule = function(a) {
                var b, c;
                2 == arguments.length ? (b = arguments[1], c = []) : (b = arguments[2], c = arguments[1]);
                var d = r(a, c, b);
                I.initialized && I.supported && d.init()
            }, I.createCoreModule = function(a, b, c) {
                r(a, b, c)
            }, I.RangePrototype = s, I.rangePrototype = new s, I.selectionPrototype = new t, I.createCoreModule("DomUtil", [], function(a, b) {
                function c(a) {
                    var b;
                    return typeof a.namespaceURI == F || null === (b = a.namespaceURI) || "http://www.w3.org/1999/xhtml" == b
                }
                function d(a) {
                    var b = a.parentNode;
                    return 1 == b.nodeType ? b : null
                }
                function e(a) {
                    for (var b = 0; a = a.previousSibling;)++b;
                    return b
                }
                function f(a) {
                    switch (a.nodeType) {
                        case 7:
                        case 10:
                            return 0;
                        case 3:
                        case 8:
                            return a.length;
                        default:
                            return a.childNodes.length
                    }
                }
                function g(a, b) {
                    var c, d = [];
                    for (c = a; c; c = c.parentNode) d.push(c);
                    for (c = b; c; c = c.parentNode) if (K(d, c)) return c;
                    return null
                }
                function h(a, b, c) {
                    for (var d = c ? b : b.parentNode; d;) {
                        if (d === a) return !0;
                        d = d.parentNode
                    }
                    return !1
                }
                function i(a, b) {
                    return h(a, b, !0)
                }
                function j(a, b, c) {
                    for (var d, e = c ? a : a.parentNode; e;) {
                        if (d = e.parentNode, d === b) return e;
                        e = d
                    }
                    return null
                }
                function k(a) {
                    var b = a.nodeType;
                    return 3 == b || 4 == b || 8 == b
                }
                function l(a) {
                    if (!a) return !1;
                    var b = a.nodeType;
                    return 3 == b || 8 == b
                }
                function m(a, b) {
                    var c = b.nextSibling,
                        d = b.parentNode;
                    return c ? d.insertBefore(a, c) : d.appendChild(a), a
                }
                function n(a, b, c) {
                    var d = a.cloneNode(!1);
                    if (d.deleteData(0, b), a.deleteData(b, a.length - b), m(d, a), c) for (var f, g = 0; f = c[g++];) f.node == a && f.offset > b ? (f.node = d, f.offset -= b) : f.node == a.parentNode && f.offset > e(a) && ++f.offset;
                    return d
                }
                function o(a) {
                    if (9 == a.nodeType) return a;
                    if (typeof a.ownerDocument != F) return a.ownerDocument;
                    if (typeof a.document != F) return a.document;
                    if (a.parentNode) return o(a.parentNode);
                    throw b.createError("getDocument: no document found for node")
                }
                function p(a) {
                    var c = o(a);
                    if (typeof c.defaultView != F) return c.defaultView;
                    if (typeof c.parentWindow != F) return c.parentWindow;
                    throw b.createError("Cannot get a window object for node")
                }
                function q(a) {
                    if (typeof a.contentDocument != F) return a.contentDocument;
                    if (typeof a.contentWindow != F) return a.contentWindow.document;
                    throw b.createError("getIframeDocument: No Document object found for iframe element")
                }
                function r(a) {
                    if (typeof a.contentWindow != F) return a.contentWindow;
                    if (typeof a.contentDocument != F) return a.contentDocument.defaultView;
                    throw b.createError("getIframeWindow: No Window object found for iframe element")
                }
                function s(a) {
                    return a && G.isHostMethod(a, "setTimeout") && G.isHostObject(a, "document")
                }
                function t(a, b, c) {
                    var d;
                    if (a ? G.isHostProperty(a, "nodeType") ? d = 1 == a.nodeType && "iframe" == a.tagName.toLowerCase() ? q(a) : o(a) : s(a) && (d = a.document) : d = document, !d) throw b.createError(c + "(): Parameter must be a Window object or DOM node");
                    return d
                }
                function u(a) {
                    for (var b; b = a.parentNode;) a = b;
                    return a
                }
                function v(a, c, d, f) {
                    var h, i, k, l, m;
                    if (a == d) return c === f ? 0 : f > c ? -1 : 1;
                    if (h = j(d, a, !0)) return c <= e(h) ? -1 : 1;
                    if (h = j(a, d, !0)) return e(h) < f ? -1 : 1;
                    if (i = g(a, d), !i) throw new Error("comparePoints error: nodes have no common ancestor");
                    if (k = a === i ? i : j(a, i, !0), l = d === i ? i : j(d, i, !0), k === l) throw b.createError("comparePoints got to case 4 and childA and childB are the same!");
                    for (m = i.firstChild; m;) {
                        if (m === k) return -1;
                        if (m === l) return 1;
                        m = m.nextSibling
                    }
                }
                function w(a) {
                    var b;
                    try {
                        return b = a.parentNode, !1
                    } catch (c) {
                        return !0
                    }
                }
                function x(a) {
                    if (!a) return "[No node]";
                    if (L && w(a)) return "[Broken node]";
                    if (k(a)) return '"' + a.data + '"';
                    if (1 == a.nodeType) {
                        var b = a.id ? ' id="' + a.id + '"' : "";
                        return "<" + a.nodeName + b + ">[index:" + e(a) + ",length:" + a.childNodes.length + "][" + (a.innerHTML || "[innerHTML not supported]").slice(0, 25) + "]"
                    }
                    return a.nodeName
                }
                function y(a) {
                    for (var b, c = o(a).createDocumentFragment(); b = a.firstChild;) c.appendChild(b);
                    return c
                }
                function z(a, b, c) {
                    var d = H(a),
                        e = a.createElement("div");
                    e.contentEditable = "" + !! c, b && (e.innerHTML = b);
                    var f = d.firstChild;
                    return f ? d.insertBefore(e, f) : d.appendChild(e), e
                }
                function A(a) {
                    return a.parentNode.removeChild(a)
                }
                function B(a) {
                    this.root = a, this._next = a
                }
                function C(a) {
                    return new B(a)
                }
                function D(a, b) {
                    this.node = a, this.offset = b
                }
                function E(a) {
                    this.code = this[a], this.codeName = a, this.message = "DOMException: " + this.codeName
                }
                var F = "undefined",
                    G = a.util,
                    H = G.getBody;
                G.areHostMethods(document, ["createDocumentFragment", "createElement", "createTextNode"]) || b.fail("document missing a Node creation method"), G.isHostMethod(document, "getElementsByTagName") || b.fail("document missing getElementsByTagName method");
                var I = document.createElement("div");
                G.areHostMethods(I, ["insertBefore", "appendChild", "cloneNode"] || !G.areHostObjects(I, ["previousSibling", "nextSibling", "childNodes", "parentNode"])) || b.fail("Incomplete Element implementation"), G.isHostProperty(I, "innerHTML") || b.fail("Element is missing innerHTML property");
                var J = document.createTextNode("test");
                G.areHostMethods(J, ["splitText", "deleteData", "insertData", "appendData", "cloneNode"] || !G.areHostObjects(I, ["previousSibling", "nextSibling", "childNodes", "parentNode"]) || !G.areHostProperties(J, ["data"])) || b.fail("Incomplete Text Node implementation");
                var K = function(a, b) {
                        for (var c = a.length; c--;) if (a[c] === b) return !0;
                        return !1
                    },
                    L = !1;
                !
                    function() {
                        var b = document.createElement("b");
                        b.innerHTML = "1";
                        var c = b.firstChild;
                        b.innerHTML = "<br />", L = w(c), a.features.crashyTextNodes = L
                    }();
                var M;
                typeof window.getComputedStyle != F ? M = function(a, b) {
                    return p(a).getComputedStyle(a, null)[b]
                } : typeof document.documentElement.currentStyle != F ? M = function(a, b) {
                    return a.currentStyle ? a.currentStyle[b] : ""
                } : b.fail("No means of obtaining computed style properties found"), B.prototype = {
                    _current: null,
                    hasNext: function() {
                        return !!this._next
                    },
                    next: function() {
                        var a, b, c = this._current = this._next;
                        if (this._current) if (a = c.firstChild) this._next = a;
                        else {
                            for (b = null; c !== this.root && !(b = c.nextSibling);) c = c.parentNode;
                            this._next = b
                        }
                        return this._current
                    },
                    detach: function() {
                        this._current = this._next = this.root = null
                    }
                }, D.prototype = {
                    equals: function(a) {
                        return !!a && this.node === a.node && this.offset == a.offset
                    },
                    inspect: function() {
                        return "[DomPosition(" + x(this.node) + ":" + this.offset + ")]"
                    },
                    toString: function() {
                        return this.inspect()
                    }
                }, E.prototype = {
                    INDEX_SIZE_ERR: 1,
                    HIERARCHY_REQUEST_ERR: 3,
                    WRONG_DOCUMENT_ERR: 4,
                    NO_MODIFICATION_ALLOWED_ERR: 7,
                    NOT_FOUND_ERR: 8,
                    NOT_SUPPORTED_ERR: 9,
                    INVALID_STATE_ERR: 11,
                    INVALID_NODE_TYPE_ERR: 24
                }, E.prototype.toString = function() {
                    return this.message
                }, a.dom = {
                    arrayContains: K,
                    isHtmlNamespace: c,
                    parentElement: d,
                    getNodeIndex: e,
                    getNodeLength: f,
                    getCommonAncestor: g,
                    isAncestorOf: h,
                    isOrIsAncestorOf: i,
                    getClosestAncestorIn: j,
                    isCharacterDataNode: k,
                    isTextOrCommentNode: l,
                    insertAfter: m,
                    splitDataNode: n,
                    getDocument: o,
                    getWindow: p,
                    getIframeWindow: r,
                    getIframeDocument: q,
                    getBody: H,
                    isWindow: s,
                    getContentDocument: t,
                    getRootContainer: u,
                    comparePoints: v,
                    isBrokenNode: w,
                    inspectNode: x,
                    getComputedStyleProperty: M,
                    createTestElement: z,
                    removeNode: A,
                    fragmentFromNodeChildren: y,
                    createIterator: C,
                    DomPosition: D
                }, a.DOMException = E
            }), I.createCoreModule("DomRange", ["DomUtil"], function(a) {
                function b(a, b) {
                    return 3 != a.nodeType && (O(a, b.startContainer) || O(a, b.endContainer))
                }
                function c(a) {
                    return a.document || P(a.startContainer)
                }
                function d(a) {
                    return V(a.startContainer)
                }
                function e(a) {
                    return new K(a.parentNode, N(a))
                }
                function f(a) {
                    return new K(a.parentNode, N(a) + 1)
                }
                function g(a, b, c) {
                    var d = 11 == a.nodeType ? a.firstChild : a;
                    return M(b) ? c == b.length ? I.insertAfter(a, b) : b.parentNode.insertBefore(a, 0 == c ? b : R(b, c)) : c >= b.childNodes.length ? b.appendChild(a) : b.insertBefore(a, b.childNodes[c]), d
                }
                function h(a, b, d) {
                    if (y(a), y(b), c(b) != c(a)) throw new L("WRONG_DOCUMENT_ERR");
                    var e = Q(a.startContainer, a.startOffset, b.endContainer, b.endOffset),
                        f = Q(a.endContainer, a.endOffset, b.startContainer, b.startOffset);
                    return d ? 0 >= e && f >= 0 : 0 > e && f > 0
                }
                function i(a) {
                    for (var b, d, e, f = c(a.range).createDocumentFragment(); d = a.next();) {
                        if (b = a.isPartiallySelectedSubtree(), d = d.cloneNode(!b), b && (e = a.getSubtreeIterator(), d.appendChild(i(e)), e.detach()), 10 == d.nodeType) throw new L("HIERARCHY_REQUEST_ERR");
                        f.appendChild(d)
                    }
                    return f
                }
                function j(a, b, c) {
                    var d, e;
                    c = c || {
                            stop: !1
                        };
                    for (var f, g; f = a.next();) if (a.isPartiallySelectedSubtree()) {
                        if (b(f) === !1) return void(c.stop = !0);
                        if (g = a.getSubtreeIterator(), j(g, b, c), g.detach(), c.stop) return
                    } else for (d = I.createIterator(f); e = d.next();) if (b(e) === !1) return void(c.stop = !0)
                }
                function k(a) {
                    for (var b; a.next();) a.isPartiallySelectedSubtree() ? (b = a.getSubtreeIterator(), k(b), b.detach()) : a.remove()
                }
                function l(a) {
                    for (var b, d, e = c(a.range).createDocumentFragment(); b = a.next();) {
                        if (a.isPartiallySelectedSubtree() ? (b = b.cloneNode(!1), d = a.getSubtreeIterator(), b.appendChild(l(d)), d.detach()) : a.remove(), 10 == b.nodeType) throw new L("HIERARCHY_REQUEST_ERR");
                        e.appendChild(b)
                    }
                    return e
                }
                function m(a, b, c) {
                    var d, e = !(!b || !b.length),
                        f = !! c;
                    e && (d = new RegExp("^(" + b.join("|") + ")$"));
                    var g = [];
                    return j(new o(a, !1), function(b) {
                        if (!(e && !d.test(b.nodeType) || f && !c(b))) {
                            var h = a.startContainer;
                            if (b != h || !M(h) || a.startOffset != h.length) {
                                var i = a.endContainer;
                                b == i && M(i) && 0 == a.endOffset || g.push(b)
                            }
                        }
                    }), g
                }
                function n(a) {
                    var b = "undefined" == typeof a.getName ? "Range" : a.getName();
                    return "[" + b + "(" + I.inspectNode(a.startContainer) + ":" + a.startOffset + ", " + I.inspectNode(a.endContainer) + ":" + a.endOffset + ")]"
                }
                function o(a, b) {
                    if (this.range = a, this.clonePartiallySelectedTextNodes = b, !a.collapsed) {
                        this.sc = a.startContainer, this.so = a.startOffset, this.ec = a.endContainer, this.eo = a.endOffset;
                        var c = a.commonAncestorContainer;
                        this.sc === this.ec && M(this.sc) ? (this.isSingleCharacterDataNode = !0, this._first = this._last = this._next = this.sc) : (this._first = this._next = this.sc !== c || M(this.sc) ? S(this.sc, c, !0) : this.sc.childNodes[this.so], this._last = this.ec !== c || M(this.ec) ? S(this.ec, c, !0) : this.ec.childNodes[this.eo - 1])
                    }
                }
                function p(a) {
                    return function(b, c) {
                        for (var d, e = c ? b : b.parentNode; e;) {
                            if (d = e.nodeType, U(a, d)) return e;
                            e = e.parentNode
                        }
                        return null
                    }
                }
                function q(a, b) {
                    if (db(a, b)) throw new L("INVALID_NODE_TYPE_ERR")
                }
                function r(a, b) {
                    if (!U(b, a.nodeType)) throw new L("INVALID_NODE_TYPE_ERR")
                }
                function s(a, b) {
                    if (0 > b || b > (M(a) ? a.length : a.childNodes.length)) throw new L("INDEX_SIZE_ERR")
                }
                function t(a, b) {
                    if (bb(a, !0) !== bb(b, !0)) throw new L("WRONG_DOCUMENT_ERR")
                }
                function u(a) {
                    if (cb(a, !0)) throw new L("NO_MODIFICATION_ALLOWED_ERR")
                }
                function v(a, b) {
                    if (!a) throw new L(b)
                }
                function w(a, b) {
                    return b <= (M(a) ? a.length : a.childNodes.length)
                }
                function x(a) {
                    return !!a.startContainer && !! a.endContainer && !(W && (I.isBrokenNode(a.startContainer) || I.isBrokenNode(a.endContainer))) && V(a.startContainer) == V(a.endContainer) && w(a.startContainer, a.startOffset) && w(a.endContainer, a.endOffset)
                }
                function y(a) {
                    if (!x(a)) throw new Error("Range error: Range is not valid. This usually happens after DOM mutation. Range: (" + a.inspect() + ")")
                }
                function z(a, b) {
                    y(a);
                    var c = a.startContainer,
                        d = a.startOffset,
                        e = a.endContainer,
                        f = a.endOffset,
                        g = c === e;
                    M(e) && f > 0 && f < e.length && R(e, f, b), M(c) && d > 0 && d < c.length && (c = R(c, d, b), g ? (f -= d, e = c) : e == c.parentNode && f >= N(c) && f++, d = 0), a.setStartAndEnd(c, d, e, f)
                }
                function A(a) {
                    y(a);
                    var b = a.commonAncestorContainer.parentNode.cloneNode(!1);
                    return b.appendChild(a.cloneContents()), b.innerHTML
                }
                function B(a) {
                    a.START_TO_START = jb, a.START_TO_END = kb, a.END_TO_END = lb, a.END_TO_START = mb, a.NODE_BEFORE = nb, a.NODE_AFTER = ob, a.NODE_BEFORE_AND_AFTER = pb, a.NODE_INSIDE = qb
                }
                function C(a) {
                    B(a), B(a.prototype)
                }
                function D(a, b) {
                    return function() {
                        y(this);
                        var c, d, e = this.startContainer,
                            g = this.startOffset,
                            h = this.commonAncestorContainer,
                            i = new o(this, !0);
                        e !== h && (c = S(e, h, !0), d = f(c), e = d.node, g = d.offset), j(i, u), i.reset();
                        var k = a(i);
                        return i.detach(), b(this, e, g, e, g), k
                    }
                }
                function E(c, d) {
                    function g(a, b) {
                        return function(c) {
                            r(c, Y), r(V(c), Z);
                            var d = (a ? e : f)(c);
                            (b ? h : i)(this, d.node, d.offset)
                        }
                    }
                    function h(a, b, c) {
                        var e = a.endContainer,
                            f = a.endOffset;
                        (b !== a.startContainer || c !== a.startOffset) && ((V(b) != V(e) || 1 == Q(b, c, e, f)) && (e = b, f = c), d(a, b, c, e, f))
                    }
                    function i(a, b, c) {
                        var e = a.startContainer,
                            f = a.startOffset;
                        (b !== a.endContainer || c !== a.endOffset) && ((V(b) != V(e) || -1 == Q(b, c, e, f)) && (e = b, f = c), d(a, e, f, b, c))
                    }
                    var j = function() {};
                    j.prototype = a.rangePrototype, c.prototype = new j, J.extend(c.prototype, {
                        setStart: function(a, b) {
                            q(a, !0), s(a, b), h(this, a, b)
                        },
                        setEnd: function(a, b) {
                            q(a, !0), s(a, b), i(this, a, b)
                        },
                        setStartAndEnd: function() {
                            var a = arguments,
                                b = a[0],
                                c = a[1],
                                e = b,
                                f = c;
                            switch (a.length) {
                                case 3:
                                    f = a[2];
                                    break;
                                case 4:
                                    e = a[2], f = a[3]
                            }
                            d(this, b, c, e, f)
                        },
                        setBoundary: function(a, b, c) {
                            this["set" + (c ? "Start" : "End")](a, b)
                        },
                        setStartBefore: g(!0, !0),
                        setStartAfter: g(!1, !0),
                        setEndBefore: g(!0, !1),
                        setEndAfter: g(!1, !1),
                        collapse: function(a) {
                            y(this), a ? d(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset) : d(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset)
                        },
                        selectNodeContents: function(a) {
                            q(a, !0), d(this, a, 0, a, T(a))
                        },
                        selectNode: function(a) {
                            q(a, !1), r(a, Y);
                            var b = e(a),
                                c = f(a);
                            d(this, b.node, b.offset, c.node, c.offset)
                        },
                        extractContents: D(l, d),
                        deleteContents: D(k, d),
                        canSurroundContents: function() {
                            y(this), u(this.startContainer), u(this.endContainer);
                            var a = new o(this, !0),
                                c = a._first && b(a._first, this) || a._last && b(a._last, this);
                            return a.detach(), !c
                        },
                        splitBoundaries: function() {
                            z(this)
                        },
                        splitBoundariesPreservingPositions: function(a) {
                            z(this, a)
                        },
                        normalizeBoundaries: function() {
                            y(this);
                            var a, b = this.startContainer,
                                c = this.startOffset,
                                e = this.endContainer,
                                f = this.endOffset,
                                g = function(a) {
                                    var b = a.nextSibling;
                                    b && b.nodeType == a.nodeType && (e = a, f = a.length, a.appendData(b.data), X(b))
                                },
                                h = function(a) {
                                    var d = a.previousSibling;
                                    if (d && d.nodeType == a.nodeType) {
                                        b = a;
                                        var g = a.length;
                                        if (c = d.length, a.insertData(0, d.data), X(d), b == e) f += c, e = b;
                                        else if (e == a.parentNode) {
                                            var h = N(a);
                                            f == h ? (e = a, f = g) : f > h && f--
                                        }
                                    }
                                },
                                i = !0;
                            if (M(e)) f == e.length ? g(e) : 0 == f && (a = e.previousSibling, a && a.nodeType == e.nodeType && (f = a.length, b == e && (i = !1), a.appendData(e.data), X(e), e = a));
                            else {
                                if (f > 0) {
                                    var j = e.childNodes[f - 1];
                                    j && M(j) && g(j)
                                }
                                i = !this.collapsed
                            }
                            if (i) {
                                if (M(b)) 0 == c ? h(b) : c == b.length && (a = b.nextSibling, a && a.nodeType == b.nodeType && (e == a && (e = b, f += b.length), b.appendData(a.data), X(a)));
                                else if (c < b.childNodes.length) {
                                    var k = b.childNodes[c];
                                    k && M(k) && h(k)
                                }
                            } else b = e, c = f;
                            d(this, b, c, e, f)
                        },
                        collapseToPoint: function(a, b) {
                            q(a, !0), s(a, b), this.setStartAndEnd(a, b)
                        }
                    }), C(c)
                }
                function F(a) {
                    a.collapsed = a.startContainer === a.endContainer && a.startOffset === a.endOffset, a.commonAncestorContainer = a.collapsed ? a.startContainer : I.getCommonAncestor(a.startContainer, a.endContainer)
                }
                function G(a, b, c, d, e) {
                    a.startContainer = b, a.startOffset = c, a.endContainer = d, a.endOffset = e, a.document = I.getDocument(b), F(a)
                }
                function H(a) {
                    this.startContainer = a, this.startOffset = 0, this.endContainer = a, this.endOffset = 0, this.document = a, F(this)
                }
                var I = a.dom,
                    J = a.util,
                    K = I.DomPosition,
                    L = a.DOMException,
                    M = I.isCharacterDataNode,
                    N = I.getNodeIndex,
                    O = I.isOrIsAncestorOf,
                    P = I.getDocument,
                    Q = I.comparePoints,
                    R = I.splitDataNode,
                    S = I.getClosestAncestorIn,
                    T = I.getNodeLength,
                    U = I.arrayContains,
                    V = I.getRootContainer,
                    W = a.features.crashyTextNodes,
                    X = I.removeNode;
                o.prototype = {
                    _current: null,
                    _next: null,
                    _first: null,
                    _last: null,
                    isSingleCharacterDataNode: !1,
                    reset: function() {
                        this._current = null, this._next = this._first
                    },
                    hasNext: function() {
                        return !!this._next
                    },
                    next: function() {
                        var a = this._current = this._next;
                        return a && (this._next = a !== this._last ? a.nextSibling : null, M(a) && this.clonePartiallySelectedTextNodes && (a === this.ec && (a = a.cloneNode(!0)).deleteData(this.eo, a.length - this.eo), this._current === this.sc && (a = a.cloneNode(!0)).deleteData(0, this.so))), a
                    },
                    remove: function() {
                        var a, b, c = this._current;
                        !M(c) || c !== this.sc && c !== this.ec ? c.parentNode && X(c) : (a = c === this.sc ? this.so : 0, b = c === this.ec ? this.eo : c.length, a != b && c.deleteData(a, b - a))
                    },
                    isPartiallySelectedSubtree: function() {
                        var a = this._current;
                        return b(a, this.range)
                    },
                    getSubtreeIterator: function() {
                        var a;
                        if (this.isSingleCharacterDataNode) a = this.range.cloneRange(), a.collapse(!1);
                        else {
                            a = new H(c(this.range));
                            var b = this._current,
                                d = b,
                                e = 0,
                                f = b,
                                g = T(b);
                            O(b, this.sc) && (d = this.sc, e = this.so), O(b, this.ec) && (f = this.ec, g = this.eo), G(a, d, e, f, g)
                        }
                        return new o(a, this.clonePartiallySelectedTextNodes)
                    },
                    detach: function() {
                        this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null
                    }
                };
                var Y = [1, 3, 4, 5, 7, 8, 10],
                    Z = [2, 9, 11],
                    $ = [5, 6, 10, 12],
                    _ = [1, 3, 4, 5, 7, 8, 10, 11],
                    ab = [1, 3, 4, 5, 7, 8],
                    bb = p([9, 11]),
                    cb = p($),
                    db = p([6, 10, 12]),
                    eb = document.createElement("style"),
                    fb = !1;
                try {
                    eb.innerHTML = "<b>x</b>", fb = 3 == eb.firstChild.nodeType
                } catch (gb) {}
                a.features.htmlParsingConforms = fb;
                var hb = fb ?
                    function(a) {
                        var b = this.startContainer,
                            c = P(b);
                        if (!b) throw new L("INVALID_STATE_ERR");
                        var d = null;
                        return 1 == b.nodeType ? d = b : M(b) && (d = I.parentElement(b)), d = null === d || "HTML" == d.nodeName && I.isHtmlNamespace(P(d).documentElement) && I.isHtmlNamespace(d) ? c.createElement("body") : d.cloneNode(!1), d.innerHTML = a, I.fragmentFromNodeChildren(d)
                    } : function(a) {
                    var b = c(this),
                        d = b.createElement("body");
                    return d.innerHTML = a, I.fragmentFromNodeChildren(d)
                }, ib = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", "commonAncestorContainer"], jb = 0, kb = 1, lb = 2, mb = 3, nb = 0, ob = 1, pb = 2, qb = 3;
                J.extend(a.rangePrototype, {
                    compareBoundaryPoints: function(a, b) {
                        y(this), t(this.startContainer, b.startContainer);
                        var c, d, e, f, g = a == mb || a == jb ? "start" : "end",
                            h = a == kb || a == jb ? "start" : "end";
                        return c = this[g + "Container"], d = this[g + "Offset"], e = b[h + "Container"], f = b[h + "Offset"], Q(c, d, e, f)
                    },
                    insertNode: function(a) {
                        if (y(this), r(a, _), u(this.startContainer), O(a, this.startContainer)) throw new L("HIERARCHY_REQUEST_ERR");
                        var b = g(a, this.startContainer, this.startOffset);
                        this.setStartBefore(b)
                    },
                    cloneContents: function() {
                        y(this);
                        var a, b;
                        if (this.collapsed) return c(this).createDocumentFragment();
                        if (this.startContainer === this.endContainer && M(this.startContainer)) return a = this.startContainer.cloneNode(!0), a.data = a.data.slice(this.startOffset, this.endOffset), b = c(this).createDocumentFragment(), b.appendChild(a), b;
                        var d = new o(this, !0);
                        return a = i(d), d.detach(), a
                    },
                    canSurroundContents: function() {
                        y(this), u(this.startContainer), u(this.endContainer);
                        var a = new o(this, !0),
                            c = a._first && b(a._first, this) || a._last && b(a._last, this);
                        return a.detach(), !c
                    },
                    surroundContents: function(a) {
                        if (r(a, ab), !this.canSurroundContents()) throw new L("INVALID_STATE_ERR");
                        var b = this.extractContents();
                        if (a.hasChildNodes()) for (; a.lastChild;) a.removeChild(a.lastChild);
                        g(a, this.startContainer, this.startOffset), a.appendChild(b), this.selectNode(a)
                    },
                    cloneRange: function() {
                        y(this);
                        for (var a, b = new H(c(this)), d = ib.length; d--;) a = ib[d], b[a] = this[a];
                        return b
                    },
                    toString: function() {
                        y(this);
                        var a = this.startContainer;
                        if (a === this.endContainer && M(a)) return 3 == a.nodeType || 4 == a.nodeType ? a.data.slice(this.startOffset, this.endOffset) : "";
                        var b = [],
                            c = new o(this, !0);
                        return j(c, function(a) {
                            (3 == a.nodeType || 4 == a.nodeType) && b.push(a.data)
                        }), c.detach(), b.join("")
                    },
                    compareNode: function(a) {
                        y(this);
                        var b = a.parentNode,
                            c = N(a);
                        if (!b) throw new L("NOT_FOUND_ERR");
                        var d = this.comparePoint(b, c),
                            e = this.comparePoint(b, c + 1);
                        return 0 > d ? e > 0 ? pb : nb : e > 0 ? ob : qb
                    },
                    comparePoint: function(a, b) {
                        return y(this), v(a, "HIERARCHY_REQUEST_ERR"), t(a, this.startContainer), Q(a, b, this.startContainer, this.startOffset) < 0 ? -1 : Q(a, b, this.endContainer, this.endOffset) > 0 ? 1 : 0
                    },
                    createContextualFragment: hb,
                    toHtml: function() {
                        return A(this)
                    },
                    intersectsNode: function(a, b) {
                        if (y(this), V(a) != d(this)) return !1;
                        var c = a.parentNode,
                            e = N(a);
                        if (!c) return !0;
                        var f = Q(c, e, this.endContainer, this.endOffset),
                            g = Q(c, e + 1, this.startContainer, this.startOffset);
                        return b ? 0 >= f && g >= 0 : 0 > f && g > 0
                    },
                    isPointInRange: function(a, b) {
                        return y(this), v(a, "HIERARCHY_REQUEST_ERR"), t(a, this.startContainer), Q(a, b, this.startContainer, this.startOffset) >= 0 && Q(a, b, this.endContainer, this.endOffset) <= 0
                    },
                    intersectsRange: function(a) {
                        return h(this, a, !1)
                    },
                    intersectsOrTouchesRange: function(a) {
                        return h(this, a, !0)
                    },
                    intersection: function(a) {
                        if (this.intersectsRange(a)) {
                            var b = Q(this.startContainer, this.startOffset, a.startContainer, a.startOffset),
                                c = Q(this.endContainer, this.endOffset, a.endContainer, a.endOffset),
                                d = this.cloneRange();
                            return -1 == b && d.setStart(a.startContainer, a.startOffset), 1 == c && d.setEnd(a.endContainer, a.endOffset), d
                        }
                        return null
                    },
                    union: function(a) {
                        if (this.intersectsOrTouchesRange(a)) {
                            var b = this.cloneRange();
                            return -1 == Q(a.startContainer, a.startOffset, this.startContainer, this.startOffset) && b.setStart(a.startContainer, a.startOffset), 1 == Q(a.endContainer, a.endOffset, this.endContainer, this.endOffset) && b.setEnd(a.endContainer, a.endOffset), b
                        }
                        throw new L("Ranges do not intersect")
                    },
                    containsNode: function(a, b) {
                        return b ? this.intersectsNode(a, !1) : this.compareNode(a) == qb
                    },
                    containsNodeContents: function(a) {
                        return this.comparePoint(a, 0) >= 0 && this.comparePoint(a, T(a)) <= 0
                    },
                    containsRange: function(a) {
                        var b = this.intersection(a);
                        return null !== b && a.equals(b)
                    },
                    containsNodeText: function(a) {
                        var b = this.cloneRange();
                        b.selectNode(a);
                        var c = b.getNodes([3]);
                        if (c.length > 0) {
                            b.setStart(c[0], 0);
                            var d = c.pop();
                            return b.setEnd(d, d.length), this.containsRange(b)
                        }
                        return this.containsNodeContents(a)
                    },
                    getNodes: function(a, b) {
                        return y(this), m(this, a, b)
                    },
                    getDocument: function() {
                        return c(this)
                    },
                    collapseBefore: function(a) {
                        this.setEndBefore(a), this.collapse(!1)
                    },
                    collapseAfter: function(a) {
                        this.setStartAfter(a), this.collapse(!0)
                    },
                    getBookmark: function(b) {
                        var d = c(this),
                            e = a.createRange(d);
                        b = b || I.getBody(d), e.selectNodeContents(b);
                        var f = this.intersection(e),
                            g = 0,
                            h = 0;
                        return f && (e.setEnd(f.startContainer, f.startOffset), g = e.toString().length, h = g + f.toString().length), {
                            start: g,
                            end: h,
                            containerNode: b
                        }
                    },
                    moveToBookmark: function(a) {
                        var b = a.containerNode,
                            c = 0;
                        this.setStart(b, 0), this.collapse(!0);
                        for (var d, e, f, g, h = [b], i = !1, j = !1; !j && (d = h.pop());) if (3 == d.nodeType) e = c + d.length, !i && a.start >= c && a.start <= e && (this.setStart(d, a.start - c), i = !0), i && a.end >= c && a.end <= e && (this.setEnd(d, a.end - c), j = !0), c = e;
                        else for (g = d.childNodes, f = g.length; f--;) h.push(g[f])
                    },
                    getName: function() {
                        return "DomRange"
                    },
                    equals: function(a) {
                        return H.rangesEqual(this, a)
                    },
                    isValid: function() {
                        return x(this)
                    },
                    inspect: function() {
                        return n(this)
                    },
                    detach: function() {}
                }), E(H, G), J.extend(H, {
                    rangeProperties: ib,
                    RangeIterator: o,
                    copyComparisonConstants: C,
                    createPrototypeRange: E,
                    inspect: n,
                    toHtml: A,
                    getRangeDocument: c,
                    rangesEqual: function(a, b) {
                        return a.startContainer === b.startContainer && a.startOffset === b.startOffset && a.endContainer === b.endContainer && a.endOffset === b.endOffset
                    }
                }), a.DomRange = H
            }), I.createCoreModule("WrappedRange", ["DomRange"], function(a, b) {
                var c, d, e = a.dom,
                    f = a.util,
                    g = e.DomPosition,
                    h = a.DomRange,
                    i = e.getBody,
                    j = e.getContentDocument,
                    k = e.isCharacterDataNode;
                if (a.features.implementsDomRange && !
                        function() {
                            function d(a) {
                                for (var b, c = m.length; c--;) b = m[c], a[b] = a.nativeRange[b];
                                a.collapsed = a.startContainer === a.endContainer && a.startOffset === a.endOffset
                            }
                            function g(a, b, c, d, e) {
                                var f = a.startContainer !== b || a.startOffset != c,
                                    g = a.endContainer !== d || a.endOffset != e,
                                    h = !a.equals(a.nativeRange);
                                (f || g || h) && (a.setEnd(d, e), a.setStart(b, c))
                            }
                            var k, l, m = h.rangeProperties;
                            c = function(a) {
                                if (!a) throw b.createError("WrappedRange: Range must be specified");
                                this.nativeRange = a, d(this)
                            }, h.createPrototypeRange(c, g), k = c.prototype, k.selectNode = function(a) {
                                this.nativeRange.selectNode(a), d(this)
                            }, k.cloneContents = function() {
                                return this.nativeRange.cloneContents()
                            }, k.surroundContents = function(a) {
                                this.nativeRange.surroundContents(a), d(this)
                            }, k.collapse = function(a) {
                                this.nativeRange.collapse(a), d(this)
                            }, k.cloneRange = function() {
                                return new c(this.nativeRange.cloneRange())
                            }, k.refresh = function() {
                                d(this)
                            }, k.toString = function() {
                                return this.nativeRange.toString()
                            };
                            var n = document.createTextNode("test");
                            i(document).appendChild(n);
                            var o = document.createRange();
                            o.setStart(n, 0), o.setEnd(n, 0);
                            try {
                                o.setStart(n, 1), k.setStart = function(a, b) {
                                    this.nativeRange.setStart(a, b), d(this)
                                }, k.setEnd = function(a, b) {
                                    this.nativeRange.setEnd(a, b), d(this)
                                }, l = function(a) {
                                    return function(b) {
                                        this.nativeRange[a](b), d(this)
                                    }
                                }
                            } catch (p) {
                                k.setStart = function(a, b) {
                                    try {
                                        this.nativeRange.setStart(a, b)
                                    } catch (c) {
                                        this.nativeRange.setEnd(a, b), this.nativeRange.setStart(a, b)
                                    }
                                    d(this)
                                }, k.setEnd = function(a, b) {
                                    try {
                                        this.nativeRange.setEnd(a, b)
                                    } catch (c) {
                                        this.nativeRange.setStart(a, b), this.nativeRange.setEnd(a, b)
                                    }
                                    d(this)
                                }, l = function(a, b) {
                                    return function(c) {
                                        try {
                                            this.nativeRange[a](c)
                                        } catch (e) {
                                            this.nativeRange[b](c), this.nativeRange[a](c)
                                        }
                                        d(this)
                                    }
                                }
                            }
                            k.setStartBefore = l("setStartBefore", "setEndBefore"), k.setStartAfter = l("setStartAfter", "setEndAfter"), k.setEndBefore = l("setEndBefore", "setStartBefore"), k.setEndAfter = l("setEndAfter", "setStartAfter"), k.selectNodeContents = function(a) {
                                this.setStartAndEnd(a, 0, e.getNodeLength(a))
                            }, o.selectNodeContents(n), o.setEnd(n, 3);
                            var q = document.createRange();
                            q.selectNodeContents(n), q.setEnd(n, 4), q.setStart(n, 2), k.compareBoundaryPoints = -1 == o.compareBoundaryPoints(o.START_TO_END, q) && 1 == o.compareBoundaryPoints(o.END_TO_START, q) ?
                                function(a, b) {
                                    return b = b.nativeRange || b, a == b.START_TO_END ? a = b.END_TO_START : a == b.END_TO_START && (a = b.START_TO_END), this.nativeRange.compareBoundaryPoints(a, b)
                                } : function(a, b) {
                                return this.nativeRange.compareBoundaryPoints(a, b.nativeRange || b)
                            };
                            var r = document.createElement("div");
                            r.innerHTML = "123";
                            var s = r.firstChild,
                                t = i(document);
                            t.appendChild(r), o.setStart(s, 1), o.setEnd(s, 2), o.deleteContents(), "13" == s.data && (k.deleteContents = function() {
                                this.nativeRange.deleteContents(), d(this)
                            }, k.extractContents = function() {
                                var a = this.nativeRange.extractContents();
                                return d(this), a
                            }), t.removeChild(r), t = null, f.isHostMethod(o, "createContextualFragment") && (k.createContextualFragment = function(a) {
                                return this.nativeRange.createContextualFragment(a)
                            }), i(document).removeChild(n), k.getName = function() {
                                return "WrappedRange"
                            }, a.WrappedRange = c, a.createNativeRange = function(a) {
                                return a = j(a, b, "createNativeRange"), a.createRange()
                            }
                        }(), a.features.implementsTextRange) {
                    var l = function(a) {
                            var b = a.parentElement(),
                                c = a.duplicate();
                            c.collapse(!0);
                            var d = c.parentElement();
                            c = a.duplicate(), c.collapse(!1);
                            var f = c.parentElement(),
                                g = d == f ? d : e.getCommonAncestor(d, f);
                            return g == b ? g : e.getCommonAncestor(b, g)
                        },
                        m = function(a) {
                            return 0 == a.compareEndPoints("StartToEnd", a)
                        },
                        n = function(a, b, c, d, f) {
                            var h = a.duplicate();
                            h.collapse(c);
                            var i = h.parentElement();
                            if (e.isOrIsAncestorOf(b, i) || (i = b), !i.canHaveHTML) {
                                var j = new g(i.parentNode, e.getNodeIndex(i));
                                return {
                                    boundaryPosition: j,
                                    nodeInfo: {
                                        nodeIndex: j.offset,
                                        containerElement: j.node
                                    }
                                }
                            }
                            var l = e.getDocument(i).createElement("span");
                            l.parentNode && e.removeNode(l);
                            for (var m, n, o, p, q, r = c ? "StartToStart" : "StartToEnd", s = f && f.containerElement == i ? f.nodeIndex : 0, t = i.childNodes.length, u = t, v = u;;) {
                                if (v == t ? i.appendChild(l) : i.insertBefore(l, i.childNodes[v]), h.moveToElementText(l), m = h.compareEndPoints(r, a), 0 == m || s == u) break;
                                if (-1 == m) {
                                    if (u == s + 1) break;
                                    s = v
                                } else u = u == s + 1 ? s : v;
                                v = Math.floor((s + u) / 2), i.removeChild(l)
                            }
                            if (q = l.nextSibling, -1 == m && q && k(q)) {
                                h.setEndPoint(c ? "EndToStart" : "EndToEnd", a);
                                var w;
                                if (/[\r\n]/.test(q.data)) {
                                    var x = h.duplicate(),
                                        y = x.text.replace(/\r\n/g, "\r").length;
                                    for (w = x.moveStart("character", y); - 1 == (m = x.compareEndPoints("StartToEnd", x));) w++, x.moveStart("character", 1)
                                } else w = h.text.length;
                                p = new g(q, w)
                            } else n = (d || !c) && l.previousSibling, o = (d || c) && l.nextSibling, p = o && k(o) ? new g(o, 0) : n && k(n) ? new g(n, n.data.length) : new g(i, e.getNodeIndex(l));
                            return e.removeNode(l), {
                                boundaryPosition: p,
                                nodeInfo: {
                                    nodeIndex: v,
                                    containerElement: i
                                }
                            }
                        },
                        o = function(a, b) {
                            var c, d, f, g, h = a.offset,
                                j = e.getDocument(a.node),
                                l = i(j).createTextRange(),
                                m = k(a.node);
                            return m ? (c = a.node, d = c.parentNode) : (g = a.node.childNodes, c = h < g.length ? g[h] : null, d = a.node), f = j.createElement("span"), f.innerHTML = "&#feff;", c ? d.insertBefore(f, c) : d.appendChild(f), l.moveToElementText(f), l.collapse(!b), d.removeChild(f), m && l[b ? "moveStart" : "moveEnd"]("character", h), l
                        };
                    d = function(a) {
                        this.textRange = a, this.refresh()
                    }, d.prototype = new h(document), d.prototype.refresh = function() {
                        var a, b, c, d = l(this.textRange);
                        m(this.textRange) ? b = a = n(this.textRange, d, !0, !0).boundaryPosition : (c = n(this.textRange, d, !0, !1), a = c.boundaryPosition, b = n(this.textRange, d, !1, !1, c.nodeInfo).boundaryPosition), this.setStart(a.node, a.offset), this.setEnd(b.node, b.offset)
                    }, d.prototype.getName = function() {
                        return "WrappedTextRange"
                    }, h.copyComparisonConstants(d);
                    var p = function(a) {
                        if (a.collapsed) return o(new g(a.startContainer, a.startOffset), !0);
                        var b = o(new g(a.startContainer, a.startOffset), !0),
                            c = o(new g(a.endContainer, a.endOffset), !1),
                            d = i(h.getRangeDocument(a)).createTextRange();
                        return d.setEndPoint("StartToStart", b), d.setEndPoint("EndToEnd", c), d
                    };
                    if (d.rangeToTextRange = p, d.prototype.toTextRange = function() {
                            return p(this)
                        }, a.WrappedTextRange = d, !a.features.implementsDomRange || a.config.preferTextRange) {
                        var q = function(a) {
                            return a("return this;")()
                        }(Function);
                        "undefined" == typeof q.Range && (q.Range = d), a.createNativeRange = function(a) {
                            return a = j(a, b, "createNativeRange"), i(a).createTextRange()
                        }, a.WrappedRange = d
                    }
                }
                a.createRange = function(c) {
                    return c = j(c, b, "createRange"), new a.WrappedRange(a.createNativeRange(c))
                }, a.createRangyRange = function(a) {
                    return a = j(a, b, "createRangyRange"), new h(a)
                }, f.createAliasForDeprecatedMethod(a, "createIframeRange", "createRange"), f.createAliasForDeprecatedMethod(a, "createIframeRangyRange", "createRangyRange"), a.addShimListener(function(b) {
                    var c = b.document;
                    "undefined" == typeof c.createRange && (c.createRange = function() {
                        return a.createRange(c)
                    }), c = b = null
                })
            }), I.createCoreModule("WrappedSelection", ["DomRange", "WrappedRange"], function(a, b) {
                function c(a) {
                    return "string" == typeof a ? /^backward(s)?$/i.test(a) : !! a
                }
                function d(a, c) {
                    if (a) {
                        if (C.isWindow(a)) return a;
                        if (a instanceof r) return a.win;
                        var d = C.getContentDocument(a, b, c);
                        return C.getWindow(d)
                    }
                    return window
                }
                function e(a) {
                    return d(a, "getWinSelection").getSelection()
                }
                function f(a) {
                    return d(a, "getDocSelection").document.selection
                }
                function g(a) {
                    var b = !1;
                    return a.anchorNode && (b = 1 == C.comparePoints(a.anchorNode, a.anchorOffset, a.focusNode, a.focusOffset)), b
                }
                function h(a, b, c) {
                    var d = c ? "end" : "start",
                        e = c ? "start" : "end";
                    a.anchorNode = b[d + "Container"], a.anchorOffset = b[d + "Offset"], a.focusNode = b[e + "Container"], a.focusOffset = b[e + "Offset"]
                }
                function i(a) {
                    var b = a.nativeSelection;
                    a.anchorNode = b.anchorNode, a.anchorOffset = b.anchorOffset, a.focusNode = b.focusNode, a.focusOffset = b.focusOffset
                }
                function j(a) {
                    a.anchorNode = a.focusNode = null, a.anchorOffset = a.focusOffset = 0, a.rangeCount = 0, a.isCollapsed = !0, a._ranges.length = 0
                }
                function k(b) {
                    var c;
                    return b instanceof F ? (c = a.createNativeRange(b.getDocument()), c.setEnd(b.endContainer, b.endOffset), c.setStart(b.startContainer, b.startOffset)) : b instanceof G ? c = b.nativeRange : J.implementsDomRange && b instanceof C.getWindow(b.startContainer).Range && (c = b), c
                }
                function l(a) {
                    if (!a.length || 1 != a[0].nodeType) return !1;
                    for (var b = 1, c = a.length; c > b; ++b) if (!C.isAncestorOf(a[0], a[b])) return !1;
                    return !0
                }
                function m(a) {
                    var c = a.getNodes();
                    if (!l(c)) throw b.createError("getSingleElementFromRange: range " + a.inspect() + " did not consist of a single element");
                    return c[0]
                }
                function n(a) {
                    return !!a && "undefined" != typeof a.text
                }
                function o(a, b) {
                    var c = new G(b);
                    a._ranges = [c], h(a, c, !1), a.rangeCount = 1, a.isCollapsed = c.collapsed
                }
                function p(b) {
                    if (b._ranges.length = 0, "None" == b.docSelection.type) j(b);
                    else {
                        var c = b.docSelection.createRange();
                        if (n(c)) o(b, c);
                        else {
                            b.rangeCount = c.length;
                            for (var d, e = L(c.item(0)), f = 0; f < b.rangeCount; ++f) d = a.createRange(e), d.selectNode(c.item(f)), b._ranges.push(d);
                            b.isCollapsed = 1 == b.rangeCount && b._ranges[0].collapsed, h(b, b._ranges[b.rangeCount - 1], !1)
                        }
                    }
                }
                function q(a, c) {
                    for (var d = a.docSelection.createRange(), e = m(c), f = L(d.item(0)), g = M(f).createControlRange(), h = 0, i = d.length; i > h; ++h) g.add(d.item(h));
                    try {
                        g.add(e)
                    } catch (j) {
                        throw b.createError("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)")
                    }
                    g.select(), p(a)
                }
                function r(a, b, c) {
                    this.nativeSelection = a, this.docSelection = b, this._ranges = [], this.win = c, this.refresh()
                }
                function s(a) {
                    a.win = a.anchorNode = a.focusNode = a._ranges = null, a.rangeCount = a.anchorOffset = a.focusOffset = 0, a.detached = !0
                }
                function t(a, b) {
                    for (var c, d, e = bb.length; e--;) if (c = bb[e], d = c.selection, "deleteAll" == b) s(d);
                    else if (c.win == a) return "delete" == b ? (bb.splice(e, 1), !0) : d;
                    return "deleteAll" == b && (bb.length = 0), null
                }
                function u(a, c) {
                    for (var d, e = L(c[0].startContainer), f = M(e).createControlRange(), g = 0, h = c.length; h > g; ++g) {
                        d = m(c[g]);
                        try {
                            f.add(d)
                        } catch (i) {
                            throw b.createError("setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)")
                        }
                    }
                    f.select(), p(a)
                }
                function v(a, b) {
                    if (a.win.document != L(b)) throw new H("WRONG_DOCUMENT_ERR")
                }
                function w(b) {
                    return function(c, d) {
                        var e;
                        this.rangeCount ? (e = this.getRangeAt(0), e["set" + (b ? "Start" : "End")](c, d)) : (e = a.createRange(this.win.document), e.setStartAndEnd(c, d)), this.setSingleRange(e, this.isBackward())
                    }
                }
                function x(a) {
                    var b = [],
                        c = new I(a.anchorNode, a.anchorOffset),
                        d = new I(a.focusNode, a.focusOffset),
                        e = "function" == typeof a.getName ? a.getName() : "Selection";
                    if ("undefined" != typeof a.rangeCount) for (var f = 0, g = a.rangeCount; g > f; ++f) b[f] = F.inspect(a.getRangeAt(f));
                    return "[" + e + "(Ranges: " + b.join(", ") + ")(anchor: " + c.inspect() + ", focus: " + d.inspect() + "]"
                }
                a.config.checkSelectionRanges = !0;
                var y, z, A = "boolean",
                    B = "number",
                    C = a.dom,
                    D = a.util,
                    E = D.isHostMethod,
                    F = a.DomRange,
                    G = a.WrappedRange,
                    H = a.DOMException,
                    I = C.DomPosition,
                    J = a.features,
                    K = "Control",
                    L = C.getDocument,
                    M = C.getBody,
                    N = F.rangesEqual,
                    O = E(window, "getSelection"),
                    P = D.isHostObject(document, "selection");
                J.implementsWinGetSelection = O, J.implementsDocSelection = P;
                var Q = P && (!O || a.config.preferTextRange);
                if (Q) y = f, a.isSelectionValid = function(a) {
                    var b = d(a, "isSelectionValid").document,
                        c = b.selection;
                    return "None" != c.type || L(c.createRange().parentElement()) == b
                };
                else {
                    if (!O) return b.fail("Neither document.selection or window.getSelection() detected."), !1;
                    y = e, a.isSelectionValid = function() {
                        return !0
                    }
                }
                a.getNativeSelection = y;
                var R = y();
                if (!R) return b.fail("Native selection was null (possibly issue 138?)"), !1;
                var S = a.createNativeRange(document),
                    T = M(document),
                    U = D.areHostProperties(R, ["anchorNode", "focusNode", "anchorOffset", "focusOffset"]);
                J.selectionHasAnchorAndFocus = U;
                var V = E(R, "extend");
                J.selectionHasExtend = V;
                var W = typeof R.rangeCount == B;
                J.selectionHasRangeCount = W;
                var X = /firefox/i.test(navigator.userAgent) ? !0 : !1,
                    Y = !0,
                    Z = V ?
                        function(b, c) {
                            var d = F.getRangeDocument(c),
                                e = a.createRange(d);
                            e.collapseToPoint(c.endContainer, c.endOffset), b.addRange(k(e)), b.extend(c.startContainer, c.startOffset)
                        } : null;
                J.selectionSupportsMultipleRanges = X, J.collapsedNonEditableSelectionsSupported = Y;
                var $, _ = !1;
                T && E(T, "createControlRange") && ($ = T.createControlRange(), D.areHostProperties($, ["item", "add"]) && (_ = !0)), J.implementsControlRange = _, z = U ?
                    function(a) {
                        return a.anchorNode === a.focusNode && a.anchorOffset === a.focusOffset
                    } : function(a) {
                    return a.rangeCount ? a.getRangeAt(a.rangeCount - 1).collapsed : !1
                };
                var ab;
                E(R, "getRangeAt") ? ab = function(a, b) {
                    try {
                        return a.getRangeAt(b)
                    } catch (c) {
                        return null
                    }
                } : U && (ab = function(b) {
                    var c = L(b.anchorNode),
                        d = a.createRange(c);
                    return d.setStartAndEnd(b.anchorNode, b.anchorOffset, b.focusNode, b.focusOffset), d.collapsed !== this.isCollapsed && d.setStartAndEnd(b.focusNode, b.focusOffset, b.anchorNode, b.anchorOffset), d
                }), r.prototype = a.selectionPrototype;
                var bb = [],
                    cb = function(a) {
                        if (a && a instanceof r) return a.refresh(), a;
                        a = d(a, "getNativeSelection");
                        var b = t(a),
                            c = y(a),
                            e = P ? f(a) : null;
                        return b ? (b.nativeSelection = c, b.docSelection = e, b.refresh()) : (b = new r(c, e, a), bb.push({
                            win: a,
                            selection: b
                        })), b
                    };
                a.getSelection = cb, D.createAliasForDeprecatedMethod(a, "getIframeSelection", "getSelection");
                var db = r.prototype;
                if (!Q && U && D.areHostMethods(R, ["removeAllRanges", "addRange"])) {
                    db.removeAllRanges = function() {
                        this.nativeSelection.removeAllRanges(), j(this)
                    };
                    var eb = function(a, b) {
                        Z(a.nativeSelection, b), a.refresh()
                    };
                    db.addRange = W ?
                        function(b, d) {
                            if (_ && P && this.docSelection.type == K) q(this, b);
                            else if (c(d) && V) eb(this, b);
                            else {
                                var e;
                                X ? e = this.rangeCount : (this.removeAllRanges(), e = 0);
                                var f = k(b).cloneRange();
                                try {
                                    this.nativeSelection.addRange(f)
                                } catch (g) {}
                                if (this.rangeCount = this.nativeSelection.rangeCount, this.rangeCount == e + 1) {
                                    if (a.config.checkSelectionRanges) {
                                        var i = ab(this.nativeSelection, this.rangeCount - 1);
                                        i && !N(i, b) && (b = new G(i))
                                    }
                                    this._ranges[this.rangeCount - 1] = b, h(this, b, hb(this.nativeSelection)), this.isCollapsed = z(this)
                                } else this.refresh()
                            }
                        } : function(a, b) {
                        c(b) && V ? eb(this, a) : (this.nativeSelection.addRange(k(a)), this.refresh())
                    }, db.setRanges = function(a) {
                        if (_ && P && a.length > 1) u(this, a);
                        else {
                            this.removeAllRanges();
                            for (var b = 0, c = a.length; c > b; ++b) this.addRange(a[b])
                        }
                    }
                } else {
                    if (!(E(R, "empty") && E(S, "select") && _ && Q)) return b.fail("No means of selecting a Range or TextRange was found"), !1;
                    db.removeAllRanges = function() {
                        try {
                            if (this.docSelection.empty(), "None" != this.docSelection.type) {
                                var a;
                                if (this.anchorNode) a = L(this.anchorNode);
                                else if (this.docSelection.type == K) {
                                    var b = this.docSelection.createRange();
                                    b.length && (a = L(b.item(0)))
                                }
                                if (a) {
                                    var c = M(a).createTextRange();
                                    c.select(), this.docSelection.empty()
                                }
                            }
                        } catch (d) {}
                        j(this)
                    }, db.addRange = function(b) {
                        this.docSelection.type == K ? q(this, b) : (a.WrappedTextRange.rangeToTextRange(b).select(), this._ranges[0] = b, this.rangeCount = 1, this.isCollapsed = this._ranges[0].collapsed, h(this, b, !1))
                    }, db.setRanges = function(a) {
                        this.removeAllRanges();
                        var b = a.length;
                        b > 1 ? u(this, a) : b && this.addRange(a[0])
                    }
                }
                db.getRangeAt = function(a) {
                    if (0 > a || a >= this.rangeCount) throw new H("INDEX_SIZE_ERR");
                    return this._ranges[a].cloneRange()
                };
                var fb;
                if (Q) fb = function(b) {
                    var c;
                    a.isSelectionValid(b.win) ? c = b.docSelection.createRange() : (c = M(b.win.document).createTextRange(), c.collapse(!0)), b.docSelection.type == K ? p(b) : n(c) ? o(b, c) : j(b)
                };
                else if (E(R, "getRangeAt") && typeof R.rangeCount == B) fb = function(b) {
                    if (_ && P && b.docSelection.type == K) p(b);
                    else if (b._ranges.length = b.rangeCount = b.nativeSelection.rangeCount, b.rangeCount) {
                        for (var c = 0, d = b.rangeCount; d > c; ++c) b._ranges[c] = new a.WrappedRange(b.nativeSelection.getRangeAt(c));
                        h(b, b._ranges[b.rangeCount - 1], hb(b.nativeSelection)), b.isCollapsed = z(b)
                    } else j(b)
                };
                else {
                    if (!U || typeof R.isCollapsed != A || typeof S.collapsed != A || !J.implementsDomRange) return b.fail("No means of obtaining a Range or TextRange from the user's selection was found"), !1;
                    fb = function(a) {
                        var b, c = a.nativeSelection;
                        c.anchorNode ? (b = ab(c, 0), a._ranges = [b], a.rangeCount = 1, i(a), a.isCollapsed = z(a)) : j(a)
                    }
                }
                db.refresh = function(a) {
                    var b = a ? this._ranges.slice(0) : null,
                        c = this.anchorNode,
                        d = this.anchorOffset;
                    if (fb(this), a) {
                        var e = b.length;
                        if (e != this._ranges.length) return !0;
                        if (this.anchorNode != c || this.anchorOffset != d) return !0;
                        for (; e--;) if (!N(b[e], this._ranges[e])) return !0;
                        return !1
                    }
                };
                var gb = function(a, b) {
                    var c = a.getAllRanges();
                    a.removeAllRanges();
                    for (var d = 0, e = c.length; e > d; ++d) N(b, c[d]) || a.addRange(c[d]);
                    a.rangeCount || j(a)
                };
                db.removeRange = _ && P ?
                    function(a) {
                        if (this.docSelection.type == K) {
                            for (var b, c = this.docSelection.createRange(), d = m(a), e = L(c.item(0)), f = M(e).createControlRange(), g = !1, h = 0, i = c.length; i > h; ++h) b = c.item(h), b !== d || g ? f.add(c.item(h)) : g = !0;
                            f.select(), p(this)
                        } else gb(this, a)
                    } : function(a) {
                    gb(this, a)
                };
                var hb;
                !Q && U && J.implementsDomRange ? (hb = g, db.isBackward = function() {
                    return hb(this)
                }) : hb = db.isBackward = function() {
                    return !1
                }, db.isBackwards = db.isBackward, db.toString = function() {
                    for (var a = [], b = 0, c = this.rangeCount; c > b; ++b) a[b] = "" + this._ranges[b];
                    return a.join("")
                }, db.collapse = function(b, c) {
                    v(this, b);
                    var d = a.createRange(b);
                    d.collapseToPoint(b, c), this.setSingleRange(d), this.isCollapsed = !0
                }, db.collapseToStart = function() {
                    if (!this.rangeCount) throw new H("INVALID_STATE_ERR");
                    var a = this._ranges[0];
                    this.collapse(a.startContainer, a.startOffset)
                }, db.collapseToEnd = function() {
                    if (!this.rangeCount) throw new H("INVALID_STATE_ERR");
                    var a = this._ranges[this.rangeCount - 1];
                    this.collapse(a.endContainer, a.endOffset)
                }, db.selectAllChildren = function(b) {
                    v(this, b);
                    var c = a.createRange(b);
                    c.selectNodeContents(b), this.setSingleRange(c)
                }, db.deleteFromDocument = function() {
                    if (_ && P && this.docSelection.type == K) {
                        for (var a, b = this.docSelection.createRange(); b.length;) a = b.item(0), b.remove(a), C.removeNode(a);
                        this.refresh()
                    } else if (this.rangeCount) {
                        var c = this.getAllRanges();
                        if (c.length) {
                            this.removeAllRanges();
                            for (var d = 0, e = c.length; e > d; ++d) c[d].deleteContents();
                            this.addRange(c[e - 1])
                        }
                    }
                }, db.eachRange = function(a, b) {
                    for (var c = 0, d = this._ranges.length; d > c; ++c) if (a(this.getRangeAt(c))) return b
                }, db.getAllRanges = function() {
                    var a = [];
                    return this.eachRange(function(b) {
                        a.push(b)
                    }), a
                }, db.setSingleRange = function(a, b) {
                    this.removeAllRanges(), this.addRange(a, b)
                }, db.callMethodOnEachRange = function(a, b) {
                    var c = [];
                    return this.eachRange(function(d) {
                        c.push(d[a].apply(d, b || []))
                    }), c
                }, db.setStart = w(!0), db.setEnd = w(!1), a.rangePrototype.select = function(a) {
                    cb(this.getDocument()).setSingleRange(this, a)
                }, db.changeEachRange = function(a) {
                    var b = [],
                        c = this.isBackward();
                    this.eachRange(function(c) {
                        a(c), b.push(c)
                    }), this.removeAllRanges(), c && 1 == b.length ? this.addRange(b[0], "backward") : this.setRanges(b)
                }, db.containsNode = function(a, b) {
                    return this.eachRange(function(c) {
                            return c.containsNode(a, b)
                        }, !0) || !1
                }, db.getBookmark = function(a) {
                    return {
                        backward: this.isBackward(),
                        rangeBookmarks: this.callMethodOnEachRange("getBookmark", [a])
                    }
                }, db.moveToBookmark = function(b) {
                    for (var c, d, e = [], f = 0; c = b.rangeBookmarks[f++];) d = a.createRange(this.win), d.moveToBookmark(c), e.push(d);
                    b.backward ? this.setSingleRange(e[0], "backward") : this.setRanges(e)
                }, db.saveRanges = function() {
                    return {
                        backward: this.isBackward(),
                        ranges: this.callMethodOnEachRange("cloneRange")
                    }
                }, db.restoreRanges = function(a) {
                    this.removeAllRanges();
                    for (var b, c = 0; b = a.ranges[c]; ++c) this.addRange(b, a.backward && 0 == c)
                }, db.toHtml = function() {
                    var a = [];
                    return this.eachRange(function(b) {
                        a.push(F.toHtml(b))
                    }), a.join("")
                }, J.implementsTextRange && (db.getNativeTextRange = function() {
                    var c;
                    if (c = this.docSelection) {
                        var d = c.createRange();
                        if (n(d)) return d;
                        throw b.createError("getNativeTextRange: selection is a control selection")
                    }
                    if (this.rangeCount > 0) return a.WrappedTextRange.rangeToTextRange(this.getRangeAt(0));
                    throw b.createError("getNativeTextRange: selection contains no range")
                }), db.getName = function() {
                    return "WrappedSelection"
                }, db.inspect = function() {
                    return x(this)
                }, db.detach = function() {
                    t(this.win, "delete"), s(this)
                }, r.detachAll = function() {
                    t(null, "deleteAll")
                }, r.inspect = x, r.isDirectionBackward = c, a.Selection = r, a.selectionPrototype = db, a.addShimListener(function(a) {
                    "undefined" == typeof a.getSelection && (a.getSelection = function() {
                        return cb(a)
                    }), a = null
                })
            });
            var N = !1,
                O = function() {
                    N || (N = !0, !I.initialized && I.config.autoInitialize && m())
                };
            G && ("complete" == document.readyState ? O() : (b(document, "addEventListener") && document.addEventListener("DOMContentLoaded", O, !1), K(window, "load", O))), a.rangy = I
        }(this), function(a) {
        return a.createModule("SaveRestore", ["WrappedRange"], function(a, b) {
            function c(a, b) {
                return (b || document).getElementById(a)
            }
            function d(a, b) {
                var c, d = "selectionBoundary_" + +new Date + "_" + ("" + Math.random()).slice(2),
                    e = o.getDocument(a.startContainer),
                    f = a.cloneRange();
                return f.collapse(b), c = e.createElement("span"), c.id = d, c.style.lineHeight = "0", c.style.display = "none", c.className = "rangySelectionBoundary", c.appendChild(e.createTextNode(r)), f.insertNode(c), c
            }
            function e(a, d, e, f) {
                var g = c(e, a);
                g ? (d[f ? "setStartBefore" : "setEndBefore"](g), p(g)) : b.warn("Marker element has been removed. Cannot restore selection.")
            }
            function f(a, b) {
                return b.compareBoundaryPoints(a.START_TO_START, a)
            }
            function g(b, c) {
                var e, f, g = a.DomRange.getRangeDocument(b),
                    h = b.toString(),
                    i = q(c);
                return b.collapsed ? (f = d(b, !1), {
                    document: g,
                    markerId: f.id,
                    collapsed: !0
                }) : (f = d(b, !1), e = d(b, !0), {
                    document: g,
                    startMarkerId: e.id,
                    endMarkerId: f.id,
                    collapsed: !1,
                    backward: i,
                    toString: function() {
                        return "original text: '" + h + "', new text: '" + b.toString() + "'"
                    }
                })
            }
            function h(d, f) {
                var g = d.document;
                "undefined" == typeof f && (f = !0);
                var h = a.createRange(g);
                if (d.collapsed) {
                    var i = c(d.markerId, g);
                    if (i) {
                        i.style.display = "inline";
                        var j = i.previousSibling;
                        j && 3 == j.nodeType ? (p(i), h.collapseToPoint(j, j.length)) : (h.collapseBefore(i), p(i))
                    } else b.warn("Marker element has been removed. Cannot restore selection.")
                } else e(g, h, d.startMarkerId, !0), e(g, h, d.endMarkerId, !1);
                return f && h.normalizeBoundaries(), h
            }
            function i(b, d) {
                var e, h, i = [],
                    j = q(d);
                b = b.slice(0), b.sort(f);
                for (var k = 0, l = b.length; l > k; ++k) i[k] = g(b[k], j);
                for (k = l - 1; k >= 0; --k) e = b[k], h = a.DomRange.getRangeDocument(e), e.collapsed ? e.collapseAfter(c(i[k].markerId, h)) : (e.setEndBefore(c(i[k].endMarkerId, h)), e.setStartAfter(c(i[k].startMarkerId, h)));
                return i
            }
            function j(c) {
                if (!a.isSelectionValid(c)) return b.warn("Cannot save selection. This usually happens when the selection is collapsed and the selection document has lost focus."), null;
                var d = a.getSelection(c),
                    e = d.getAllRanges(),
                    f = 1 == e.length && d.isBackward(),
                    g = i(e, f);
                return f ? d.setSingleRange(e[0], f) : d.setRanges(e), {
                    win: c,
                    rangeInfos: g,
                    restored: !1
                }
            }
            function k(a) {
                for (var b = [], c = a.length, d = c - 1; d >= 0; d--) b[d] = h(a[d], !0);
                return b
            }
            function l(b, c) {
                if (!b.restored) {
                    var d = b.rangeInfos,
                        e = a.getSelection(b.win),
                        f = k(d),
                        g = d.length;
                    1 == g && c && a.features.selectionHasExtend && d[0].backward ? (e.removeAllRanges(), e.addRange(f[0], !0)) : e.setRanges(f), b.restored = !0
                }
            }
            function m(a, b) {
                var d = c(b, a);
                d && p(d)
            }
            function n(a) {
                for (var b, c = a.rangeInfos, d = 0, e = c.length; e > d; ++d) b = c[d], b.collapsed ? m(a.doc, b.markerId) : (m(a.doc, b.startMarkerId), m(a.doc, b.endMarkerId))
            }
            var o = a.dom,
                p = o.removeNode,
                q = a.Selection.isDirectionBackward,
                r = "﻿";
            a.util.extend(a, {
                saveRange: g,
                restoreRange: h,
                saveRanges: i,
                restoreRanges: k,
                saveSelection: j,
                restoreSelection: l,
                removeMarkerElement: m,
                removeMarkers: n
            })
        }), a
    }(this.rangy), function(a) {
        return a.createModule("TextRange", ["WrappedSelection"], function(a, b) {
            function c(a, b) {
                function c(a, b, c) {
                    h.push({
                        start: a,
                        end: b,
                        isWord: c
                    })
                }
                for (var d, e, f, g = a.join(""), h = [], i = 0; d = b.wordRegex.exec(g);) {
                    if (e = d.index, f = e + d[0].length, e > i && c(i, e, !1), b.includeTrailingSpace) for (; _.test(a[f]);)++f;
                    c(e, f, !0), i = f
                }
                return i < a.length && c(i, a.length, !1), h
            }
            function d(a, b) {
                for (var c = a.slice(b.start, b.end), d = {
                    isWord: b.isWord,
                    chars: c,
                    toString: function() {
                        return c.join("")
                    }
                }, e = 0, f = c.length; f > e; ++e) c[e].token = d;
                return d
            }
            function e(a, b, c) {
                for (var e, f = c(a, b), g = [], h = 0; e = f[h++];) g.push(d(a, e));
                return g
            }
            function f(a) {
                var b = a || "",
                    c = "string" == typeof b ? b.split("") : b;
                return c.sort(function(a, b) {
                    return a.charCodeAt(0) - b.charCodeAt(0)
                }), c.join("").replace(/(.)\1+/g, "$1")
            }
            function g(a) {
                var b, c;
                return a ? (b = a.language || ab, c = {}, V(c, hb[b] || hb[ab]), V(c, a), c) : hb[ab]
            }
            function h(a, b) {
                var c = W(a, b);
                return b.hasOwnProperty("wordOptions") && (c.wordOptions = g(c.wordOptions)), b.hasOwnProperty("characterOptions") && (c.characterOptions = W(c.characterOptions, fb)), c
            }
            function i(a, b) {
                var c = mb(a, "display", b),
                    d = a.tagName.toLowerCase();
                return "block" == c && P && nb.hasOwnProperty(d) ? nb[d] : c
            }
            function j(a) {
                for (var b = o(a), c = 0, d = b.length; d > c; ++c) if (1 == b[c].nodeType && "none" == i(b[c])) return !0;
                return !1
            }
            function k(a) {
                var b;
                return 3 == a.nodeType && (b = a.parentNode) && "hidden" == mb(b, "visibility")
            }
            function l(a) {
                return a && (1 == a.nodeType && !/^(inline(-block|-table)?|none)$/.test(i(a)) || 9 == a.nodeType || 11 == a.nodeType)
            }
            function m(a) {
                return T.isCharacterDataNode(a) || !/^(area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param)$/i.test(a.nodeName)
            }
            function n(a) {
                for (var b = []; a.parentNode;) b.unshift(a.parentNode), a = a.parentNode;
                return b
            }
            function o(a) {
                return n(a).concat([a])
            }
            function p(a) {
                for (; a && !a.nextSibling;) a = a.parentNode;
                return a ? a.nextSibling : null
            }
            function q(a, b) {
                return !b && a.hasChildNodes() ? a.firstChild : p(a)
            }
            function r(a) {
                var b = a.previousSibling;
                if (b) {
                    for (a = b; a.hasChildNodes();) a = a.lastChild;
                    return a
                }
                var c = a.parentNode;
                return c && 1 == c.nodeType ? c : null
            }
            function s(a) {
                if (!a || 3 != a.nodeType) return !1;
                var b = a.data;
                if ("" === b) return !0;
                var c = a.parentNode;
                if (!c || 1 != c.nodeType) return !1;
                var d = mb(a.parentNode, "whiteSpace");
                return /^[\t\n\r ]+$/.test(b) && /^(normal|nowrap)$/.test(d) || /^[\t\r ]+$/.test(b) && "pre-line" == d
            }
            function t(a) {
                if ("" === a.data) return !0;
                if (!s(a)) return !1;
                var b = a.parentNode;
                return b ? j(a) ? !0 : !1 : !0
            }
            function u(a) {
                var b = a.nodeType;
                return 7 == b || 8 == b || j(a) || /^(script|style)$/i.test(a.nodeName) || k(a) || t(a)
            }
            function v(a, b) {
                var c = a.nodeType;
                return 7 == c || 8 == c || 1 == c && "none" == i(a, b)
            }
            function w() {
                this.store = {}
            }
            function x(a, b, c) {
                return function(d) {
                    var e = this.cache;
                    if (e.hasOwnProperty(a)) return ob++, e[a];
                    pb++;
                    var f = b.call(this, c ? this[c] : this, d);
                    return e[a] = f, f
                }
            }
            function y(a, b) {
                this.node = a, this.session = b, this.cache = new w, this.positions = new w
            }
            function z(a, b) {
                this.offset = b, this.nodeWrapper = a, this.node = a.node, this.session = a.session, this.cache = new w
            }
            function A() {
                return "[Position(" + T.inspectNode(this.node) + ":" + this.offset + ")]"
            }
            function B() {
                return D(), Cb = new Db
            }
            function C() {
                return Cb || B()
            }
            function D() {
                Cb && Cb.detach(), Cb = null
            }
            function E(a, c, d, e) {
                function f() {
                    var a = null;
                    return c ? (a = h, i || (h = h.previousVisible(), i = !h || d && h.equals(d))) : i || (a = h = h.nextVisible(), i = !h || d && h.equals(d)), i && (h = null), a
                }
                d && (c ? u(d.node) && (d = a.previousVisible()) : u(d.node) && (d = d.nextVisible()));
                var g, h = a,
                    i = !1,
                    j = !1;
                return {
                    next: function() {
                        if (j) return j = !1, g;
                        for (var a, b; a = f();) if (b = a.getCharacter(e)) return g = a, a;
                        return null
                    },
                    rewind: function() {
                        if (!g) throw b.createError("createCharacterIterator: cannot rewind. Only one position can be rewound.");
                        j = !0
                    },
                    dispose: function() {
                        a = d = null
                    }
                }
            }
            function F(a, b, c) {
                function d(a) {
                    for (var b, c, d = [], e = a ? f : g, h = !1, i = !1; b = e.next();) {
                        if (c = b.character, $.test(c)) i && (i = !1, h = !0);
                        else {
                            if (h) {
                                e.rewind();
                                break
                            }
                            i = !0
                        }
                        d.push(b)
                    }
                    return d
                }
                var f = E(a, !1, null, b),
                    g = E(a, !0, null, b),
                    h = c.tokenizer,
                    i = d(!0),
                    j = d(!1).reverse(),
                    k = e(j.concat(i), c, h),
                    l = i.length ? k.slice(Eb(k, i[0].token)) : [],
                    m = j.length ? k.slice(0, Eb(k, j.pop().token) + 1) : [];
                return {
                    nextEndToken: function() {
                        for (var a, b; 1 == l.length && !(a = l[0]).isWord && (b = d(!0)).length > 0;) l = e(a.chars.concat(b), c, h);
                        return l.shift()
                    },
                    previousStartToken: function() {
                        for (var a, b; 1 == m.length && !(a = m[0]).isWord && (b = d(!1)).length > 0;) m = e(b.reverse().concat(a.chars), c, h);
                        return m.pop()
                    },
                    dispose: function() {
                        f.dispose(), g.dispose(), l = m = null
                    }
                }
            }
            function G(a, b, c, d, e) {
                var f, g, h, i, j = 0,
                    k = a,
                    l = Math.abs(c);
                if (0 !== c) {
                    var m = 0 > c;
                    switch (b) {
                        case R:
                            for (g = E(a, m, null, d);
                                 (f = g.next()) && l > j;)++j, k = f;
                            h = f, g.dispose();
                            break;
                        case S:
                            for (var n = F(a, d, e), o = m ? n.previousStartToken : n.nextEndToken;
                                 (i = o()) && l > j;) i.isWord && (++j, k = m ? i.chars[0] : i.chars[i.chars.length - 1]);
                            break;
                        default:
                            throw new Error("movePositionBy: unit '" + b + "' not implemented")
                    }
                    m ? (k = k.previousVisible(), j = -j) : k && k.isLeadingSpace && !k.isTrailingSpace && (b == S && (g = E(a, !1, null, d), h = g.next(), g.dispose()), h && (k = h.previousVisible()))
                }
                return {
                    position: k,
                    unitsMoved: j
                }
            }
            function H(a, b, c, d) {
                var e = a.getRangeBoundaryPosition(b, !0),
                    f = a.getRangeBoundaryPosition(b, !1),
                    g = d ? f : e,
                    h = d ? e : f;
                return E(g, !! d, h, c)
            }
            function I(a, b, c) {
                for (var d, e = [], f = H(a, b, c); d = f.next();) e.push(d);
                return f.dispose(), e
            }
            function J(b, c, d) {
                var e = a.createRange(b.node);
                return e.setStartAndEnd(b.node, b.offset, c.node, c.offset), !e.expand("word", {
                    wordOptions: d
                })
            }
            function K(a, b, c, d, e) {
                function f(a, b) {
                    var c = p[a].previousVisible(),
                        d = p[b - 1],
                        f = !e.wholeWordsOnly || J(c, d, e.wordOptions);
                    return {
                        startPos: c,
                        endPos: d,
                        valid: f
                    }
                }
                for (var g, h, i, j, k, l, m = bb(e.direction), n = E(a, m, a.session.getRangeBoundaryPosition(d, m), e.characterOptions), o = "", p = [], q = null; g = n.next();) if (h = g.character, c || e.caseSensitive || (h = h.toLowerCase()), m ? (p.unshift(g), o = h + o) : (p.push(g), o += h), c) {
                    if (k = b.exec(o)) if (i = k.index, j = i + k[0].length, l) {
                        if (!m && j < o.length || m && i > 0) {
                            q = f(i, j);
                            break
                        }
                    } else l = !0
                } else if (-1 != (i = o.indexOf(b))) {
                    q = f(i, i + b.length);
                    break
                }
                return l && (q = f(i, j)), n.dispose(), q
            }
            function L(a) {
                return function() {
                    var b = !! Cb,
                        c = C(),
                        d = [c].concat(U.toArray(arguments)),
                        e = a.apply(this, d);
                    return b || D(), e
                }
            }
            function M(a, b) {
                return L(function(c, d, e, f) {
                    typeof e == Q && (e = d, d = R), f = h(f, jb);
                    var g = a;
                    b && (g = e >= 0, this.collapse(!g));
                    var i = G(c.getRangeBoundaryPosition(this, g), d, e, f.characterOptions, f.wordOptions),
                        j = i.position;
                    return this[g ? "setStart" : "setEnd"](j.node, j.offset), i.unitsMoved
                })
            }
            function N(a) {
                return L(function(b, c) {
                    c = W(c, fb);
                    for (var d, e = H(b, this, c, !a), f = 0;
                         (d = e.next()) && $.test(d.character);)++f;
                    e.dispose();
                    var g = f > 0;
                    return g && this[a ? "moveStart" : "moveEnd"]("character", a ? f : -f, {
                        characterOptions: c
                    }), g
                })
            }
            function O(a) {
                return L(function(b, c) {
                    var d = !1;
                    return this.changeEachRange(function(b) {
                        d = b[a](c) || d
                    }), d
                })
            }
            var P, Q = "undefined",
                R = "character",
                S = "word",
                T = a.dom,
                U = a.util,
                V = U.extend,
                W = U.createOptions,
                X = T.getBody,
                Y = /^[ \t\f\r\n]+$/,
                Z = /^[ \t\f\r]+$/,
                $ = /^[\t-\r \u0085\u00A0\u1680\u180E\u2000-\u200B\u2028\u2029\u202F\u205F\u3000]+$/,
                _ = /^[\t \u00A0\u1680\u180E\u2000-\u200B\u202F\u205F\u3000]+$/,
                ab = "en",
                bb = a.Selection.isDirectionBackward,
                cb = (/Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor) ? !0 : !1, !1),
                db = !1,
                eb = !0,
                fb = {
                    includeBlockContentTrailingSpace: !0,
                    includeSpaceBeforeBr: !0,
                    includeSpaceBeforeBlock: !0,
                    includePreLineTrailingSpace: !0,
                    ignoreCharacters: ""
                },
                gb = {
                    includeBlockContentTrailingSpace: !eb,
                    includeSpaceBeforeBr: !cb,
                    includeSpaceBeforeBlock: !db,
                    includePreLineTrailingSpace: !0
                },
                hb = {
                    en: {
                        wordRegex: /[a-z0-9]+('[a-z0-9]+)*/gi,
                        includeTrailingSpace: !1,
                        tokenizer: c
                    }
                },
                ib = {
                    caseSensitive: !1,
                    withinRange: null,
                    wholeWordsOnly: !1,
                    wrap: !1,
                    direction: "forward",
                    wordOptions: null,
                    characterOptions: null
                },
                jb = {
                    wordOptions: null,
                    characterOptions: null
                },
                kb = {
                    wordOptions: null,
                    characterOptions: null,
                    trim: !1,
                    trimStart: !0,
                    trimEnd: !0
                },
                lb = {
                    wordOptions: null,
                    characterOptions: null,
                    direction: "forward"
                },
                mb = T.getComputedStyleProperty;
            !
                function() {
                    var a = document.createElement("table"),
                        b = X(document);
                    b.appendChild(a), P = "block" == mb(a, "display"), b.removeChild(a)
                }();
            var nb = {
                table: "table",
                caption: "table-caption",
                colgroup: "table-column-group",
                col: "table-column",
                thead: "table-header-group",
                tbody: "table-row-group",
                tfoot: "table-footer-group",
                tr: "table-row",
                td: "table-cell",
                th: "table-cell"
            };
            w.prototype = {
                get: function(a) {
                    return this.store.hasOwnProperty(a) ? this.store[a] : null
                },
                set: function(a, b) {
                    return this.store[a] = b
                }
            };
            var ob = 0,
                pb = 0,
                qb = {
                    getPosition: function(a) {
                        var b = this.positions;
                        return b.get(a) || b.set(a, new z(this, a))
                    },
                    toString: function() {
                        return "[NodeWrapper(" + T.inspectNode(this.node) + ")]"
                    }
                };
            y.prototype = qb;
            var rb = "EMPTY",
                sb = "NON_SPACE",
                tb = "UNCOLLAPSIBLE_SPACE",
                ub = "COLLAPSIBLE_SPACE",
                vb = "TRAILING_SPACE_BEFORE_BLOCK",
                wb = "TRAILING_SPACE_IN_BLOCK",
                xb = "TRAILING_SPACE_BEFORE_BR",
                yb = "PRE_LINE_TRAILING_SPACE_BEFORE_LINE_BREAK",
                zb = "TRAILING_LINE_BREAK_AFTER_BR",
                Ab = "INCLUDED_TRAILING_LINE_BREAK_AFTER_BR";
            V(qb, {
                isCharacterDataNode: x("isCharacterDataNode", T.isCharacterDataNode, "node"),
                getNodeIndex: x("nodeIndex", T.getNodeIndex, "node"),
                getLength: x("nodeLength", T.getNodeLength, "node"),
                containsPositions: x("containsPositions", m, "node"),
                isWhitespace: x("isWhitespace", s, "node"),
                isCollapsedWhitespace: x("isCollapsedWhitespace", t, "node"),
                getComputedDisplay: x("computedDisplay", i, "node"),
                isCollapsed: x("collapsed", u, "node"),
                isIgnored: x("ignored", v, "node"),
                next: x("nextPos", q, "node"),
                previous: x("previous", r, "node"),
                getTextNodeInfo: x("textNodeInfo", function(a) {
                    var b = null,
                        c = !1,
                        d = mb(a.parentNode, "whiteSpace"),
                        e = "pre-line" == d;
                    return e ? (b = Z, c = !0) : ("normal" == d || "nowrap" == d) && (b = Y, c = !0), {
                        node: a,
                        text: a.data,
                        spaceRegex: b,
                        collapseSpaces: c,
                        preLine: e
                    }
                }, "node"),
                hasInnerText: x("hasInnerText", function(a, b) {
                    for (var c = this.session, d = c.getPosition(a.parentNode, this.getNodeIndex() + 1), e = c.getPosition(a, 0), f = b ? d : e, g = b ? e : d; f !== g;) {
                        if (f.prepopulateChar(), f.isDefinitelyNonEmpty()) return !0;
                        f = b ? f.previousVisible() : f.nextVisible()
                    }
                    return !1
                }, "node"),
                isRenderedBlock: x("isRenderedBlock", function(a) {
                    for (var b = a.getElementsByTagName("br"), c = 0, d = b.length; d > c; ++c) if (!u(b[c])) return !0;
                    return this.hasInnerText()
                }, "node"),
                getTrailingSpace: x("trailingSpace", function(a) {
                    if ("br" == a.tagName.toLowerCase()) return "";
                    switch (this.getComputedDisplay()) {
                        case "inline":
                            for (var b = a.lastChild; b;) {
                                if (!v(b)) return 1 == b.nodeType ? this.session.getNodeWrapper(b).getTrailingSpace() : "";
                                b = b.previousSibling
                            }
                            break;
                        case "inline-block":
                        case "inline-table":
                        case "none":
                        case "table-column":
                        case "table-column-group":
                            break;
                        case "table-cell":
                            return "	";
                        default:
                            return this.isRenderedBlock(!0) ? "\n" : ""
                    }
                    return ""
                }, "node"),
                getLeadingSpace: x("leadingSpace", function() {
                    switch (this.getComputedDisplay()) {
                        case "inline":
                        case "inline-block":
                        case "inline-table":
                        case "none":
                        case "table-column":
                        case "table-column-group":
                        case "table-cell":
                            break;
                        default:
                            return this.isRenderedBlock(!1) ? "\n" : ""
                    }
                    return ""
                }, "node")
            });
            var Bb = {
                character: "",
                characterType: rb,
                isBr: !1,
                prepopulateChar: function() {
                    var a = this;
                    if (!a.prepopulatedChar) {
                        var b = a.node,
                            c = a.offset,
                            d = "",
                            e = rb,
                            f = !1;
                        if (c > 0) if (3 == b.nodeType) {
                            var g = b.data,
                                h = g.charAt(c - 1),
                                i = a.nodeWrapper.getTextNodeInfo(),
                                j = i.spaceRegex;
                            i.collapseSpaces ? j.test(h) ? c > 1 && j.test(g.charAt(c - 2)) || (i.preLine && "\n" === g.charAt(c) ? (d = " ", e = yb) : (d = " ", e = ub)) : (d = h, e = sb, f = !0) : (d = h, e = tb, f = !0)
                        } else {
                            var k = b.childNodes[c - 1];
                            if (k && 1 == k.nodeType && !u(k) && ("br" == k.tagName.toLowerCase() ? (d = "\n", a.isBr = !0, e = ub, f = !1) : a.checkForTrailingSpace = !0), !d) {
                                var l = b.childNodes[c];
                                l && 1 == l.nodeType && !u(l) && (a.checkForLeadingSpace = !0)
                            }
                        }
                        a.prepopulatedChar = !0, a.character = d, a.characterType = e, a.isCharInvariant = f
                    }
                },
                isDefinitelyNonEmpty: function() {
                    var a = this.characterType;
                    return a == sb || a == tb
                },
                resolveLeadingAndTrailingSpaces: function() {
                    if (this.prepopulatedChar || this.prepopulateChar(), this.checkForTrailingSpace) {
                        var a = this.session.getNodeWrapper(this.node.childNodes[this.offset - 1]).getTrailingSpace();
                        a && (this.isTrailingSpace = !0, this.character = a, this.characterType = ub), this.checkForTrailingSpace = !1
                    }
                    if (this.checkForLeadingSpace) {
                        var b = this.session.getNodeWrapper(this.node.childNodes[this.offset]).getLeadingSpace();
                        b && (this.isLeadingSpace = !0, this.character = b, this.characterType = ub), this.checkForLeadingSpace = !1
                    }
                },
                getPrecedingUncollapsedPosition: function(a) {
                    for (var b, c = this; c = c.previousVisible();) if (b = c.getCharacter(a), "" !== b) return c;
                    return null
                },
                getCharacter: function(a) {
                    function b() {
                        return n || (k = o.getPrecedingUncollapsedPosition(a), n = !0), k
                    }
                    this.resolveLeadingAndTrailingSpaces();
                    var c, d = this.character,
                        e = f(a.ignoreCharacters),
                        g = "" !== d && e.indexOf(d) > -1;
                    if (this.isCharInvariant) return c = g ? "" : d;
                    var h = ["character", a.includeSpaceBeforeBr, a.includeBlockContentTrailingSpace, a.includePreLineTrailingSpace, e].join("_"),
                        i = this.cache.get(h);
                    if (null !== i) return i;
                    var j, k, l = "",
                        m = this.characterType == ub,
                        n = !1,
                        o = this;
                    return m && (this.type == Ab ? l = "\n" : " " == d && (!b() || k.isTrailingSpace || "\n" == k.character || " " == k.character && k.characterType == ub) || ("\n" == d && this.isLeadingSpace ? b() && "\n" != k.character && (l = "\n") : (j = this.nextUncollapsed(), j && (j.isBr ? this.type = xb : j.isTrailingSpace && "\n" == j.character ? this.type = wb : j.isLeadingSpace && "\n" == j.character && (this.type = vb), "\n" == j.character ? (this.type != xb || a.includeSpaceBeforeBr) && (this.type != vb || a.includeSpaceBeforeBlock) && (this.type == wb && j.isTrailingSpace && !a.includeBlockContentTrailingSpace || (this.type != yb || j.type != sb || a.includePreLineTrailingSpace) && ("\n" == d ? j.isTrailingSpace ? this.isTrailingSpace || this.isBr && (j.type = zb, b() && k.isLeadingSpace && !k.isTrailingSpace && "\n" == k.character ? j.character = "" : j.type = Ab) : l = "\n" : " " == d && (l = " "))) : l = d)))), e.indexOf(l) > -1 && (l = ""), this.cache.set(h, l), l
                },
                equals: function(a) {
                    return !!a && this.node === a.node && this.offset === a.offset
                },
                inspect: A,
                toString: function() {
                    return this.character
                }
            };
            z.prototype = Bb, V(Bb, {
                next: x("nextPos", function(a) {
                    var b = a.nodeWrapper,
                        c = a.node,
                        d = a.offset,
                        e = b.session;
                    if (!c) return null;
                    var f, g, h;
                    return d == b.getLength() ? (f = c.parentNode, g = f ? b.getNodeIndex() + 1 : 0) : b.isCharacterDataNode() ? (f = c, g = d + 1) : (h = c.childNodes[d], e.getNodeWrapper(h).containsPositions() ? (f = h, g = 0) : (f = c, g = d + 1)), f ? e.getPosition(f, g) : null
                }),
                previous: x("previous", function(a) {
                    var b, c, d, e = a.nodeWrapper,
                        f = a.node,
                        g = a.offset,
                        h = e.session;
                    return 0 == g ? (b = f.parentNode, c = b ? e.getNodeIndex() : 0) : e.isCharacterDataNode() ? (b = f, c = g - 1) : (d = f.childNodes[g - 1], h.getNodeWrapper(d).containsPositions() ? (b = d, c = T.getNodeLength(d)) : (b = f, c = g - 1)), b ? h.getPosition(b, c) : null
                }),
                nextVisible: x("nextVisible", function(a) {
                    var b = a.next();
                    if (!b) return null;
                    var c = b.nodeWrapper,
                        d = b.node,
                        e = b;
                    return c.isCollapsed() && (e = c.session.getPosition(d.parentNode, c.getNodeIndex() + 1)), e
                }),
                nextUncollapsed: x("nextUncollapsed", function(a) {
                    for (var b = a; b = b.nextVisible();) if (b.resolveLeadingAndTrailingSpaces(), "" !== b.character) return b;
                    return null
                }),
                previousVisible: x("previousVisible", function(a) {
                    var b = a.previous();
                    if (!b) return null;
                    var c = b.nodeWrapper,
                        d = b.node,
                        e = b;
                    return c.isCollapsed() && (e = c.session.getPosition(d.parentNode, c.getNodeIndex())), e
                })
            });
            var Cb = null,
                Db = function() {
                    function a(a) {
                        var b = new w;
                        return {
                            get: function(c) {
                                var d = b.get(c[a]);
                                if (d) for (var e, f = 0; e = d[f++];) if (e.node === c) return e;
                                return null
                            },
                            set: function(c) {
                                var d = c.node[a],
                                    e = b.get(d) || b.set(d, []);
                                e.push(c)
                            }
                        }
                    }
                    function b() {
                        this.initCaches()
                    }
                    var c = U.isHostProperty(document.documentElement, "uniqueID");
                    return b.prototype = {
                        initCaches: function() {
                            this.elementCache = c ?
                                function() {
                                    var a = new w;
                                    return {
                                        get: function(b) {
                                            return a.get(b.uniqueID)
                                        },
                                        set: function(b) {
                                            a.set(b.node.uniqueID, b)
                                        }
                                    }
                                }() : a("tagName"), this.textNodeCache = a("data"), this.otherNodeCache = a("nodeName")
                        },
                        getNodeWrapper: function(a) {
                            var b;
                            switch (a.nodeType) {
                                case 1:
                                    b = this.elementCache;
                                    break;
                                case 3:
                                    b = this.textNodeCache;
                                    break;
                                default:
                                    b = this.otherNodeCache
                            }
                            var c = b.get(a);
                            return c || (c = new y(a, this), b.set(c)), c
                        },
                        getPosition: function(a, b) {
                            return this.getNodeWrapper(a).getPosition(b)
                        },
                        getRangeBoundaryPosition: function(a, b) {
                            var c = b ? "start" : "end";
                            return this.getPosition(a[c + "Container"], a[c + "Offset"])
                        },
                        detach: function() {
                            this.elementCache = this.textNodeCache = this.otherNodeCache = null
                        }
                    }, b
                }();
            V(T, {
                nextNode: q,
                previousNode: r
            });
            var Eb = Array.prototype.indexOf ?
                function(a, b) {
                    return a.indexOf(b)
                } : function(a, b) {
                for (var c = 0, d = a.length; d > c; ++c) if (a[c] === b) return c;
                return -1
            };
            V(a.rangePrototype, {
                moveStart: M(!0, !1),
                moveEnd: M(!1, !1),
                move: M(!0, !0),
                trimStart: N(!0),
                trimEnd: N(!1),
                trim: L(function(a, b) {
                    var c = this.trimStart(b),
                        d = this.trimEnd(b);
                    return c || d
                }),
                expand: L(function(a, b, c) {
                    var d = !1;
                    c = h(c, kb);
                    var e = c.characterOptions;
                    if (b || (b = R), b == S) {
                        var f, g, i = c.wordOptions,
                            j = a.getRangeBoundaryPosition(this, !0),
                            k = a.getRangeBoundaryPosition(this, !1),
                            l = F(j, e, i),
                            m = l.nextEndToken(),
                            n = m.chars[0].previousVisible();
                        if (this.collapsed) f = m;
                        else {
                            var o = F(k, e, i);
                            f = o.previousStartToken()
                        }
                        return g = f.chars[f.chars.length - 1], n.equals(j) || (this.setStart(n.node, n.offset), d = !0), g && !g.equals(k) && (this.setEnd(g.node, g.offset), d = !0), c.trim && (c.trimStart && (d = this.trimStart(e) || d), c.trimEnd && (d = this.trimEnd(e) || d)), d
                    }
                    return this.moveEnd(R, 1, c)
                }),
                text: L(function(a, b) {
                    return this.collapsed ? "" : I(a, this, W(b, fb)).join("")
                }),
                selectCharacters: L(function(a, b, c, d, e) {
                    var f = {
                        characterOptions: e
                    };
                    b || (b = X(this.getDocument())), this.selectNodeContents(b), this.collapse(!0), this.moveStart("character", c, f), this.collapse(!0), this.moveEnd("character", d - c, f)
                }),
                toCharacterRange: L(function(a, b, c) {
                    b || (b = X(this.getDocument()));
                    var d, e, f = b.parentNode,
                        g = T.getNodeIndex(b),
                        h = -1 == T.comparePoints(this.startContainer, this.endContainer, f, g),
                        i = this.cloneRange();
                    return h ? (i.setStartAndEnd(this.startContainer, this.startOffset, f, g), d = -i.text(c).length) : (i.setStartAndEnd(f, g, this.startContainer, this.startOffset), d = i.text(c).length), e = d + this.text(c).length, {
                        start: d,
                        end: e
                    }
                }),
                findText: L(function(b, c, d) {
                    d = h(d, ib), d.wholeWordsOnly && (d.wordOptions.includeTrailingSpace = !1);
                    var e = bb(d.direction),
                        f = d.withinRange;
                    f || (f = a.createRange(), f.selectNodeContents(this.getDocument()));
                    var g = c,
                        i = !1;
                    "string" == typeof g ? d.caseSensitive || (g = g.toLowerCase()) : i = !0;
                    var j = b.getRangeBoundaryPosition(this, !e),
                        k = f.comparePoint(j.node, j.offset); - 1 === k ? j = b.getRangeBoundaryPosition(f, !0) : 1 === k && (j = b.getRangeBoundaryPosition(f, !1));
                    for (var l, m = j, n = !1;;) if (l = K(m, g, i, f, d)) {
                        if (l.valid) return this.setStartAndEnd(l.startPos.node, l.startPos.offset, l.endPos.node, l.endPos.offset), !0;
                        m = e ? l.startPos : l.endPos
                    } else {
                        if (!d.wrap || n) return !1;
                        f = f.cloneRange(), m = b.getRangeBoundaryPosition(f, !e), f.setBoundary(j.node, j.offset, e), n = !0
                    }
                }),
                pasteHtml: function(a) {
                    if (this.deleteContents(), a) {
                        var b = this.createContextualFragment(a),
                            c = b.lastChild;
                        this.insertNode(b), this.collapseAfter(c)
                    }
                }
            }), V(a.selectionPrototype, {
                expand: L(function(a, b, c) {
                    this.changeEachRange(function(a) {
                        a.expand(b, c)
                    })
                }),
                move: L(function(a, b, c, d) {
                    var e = 0;
                    if (this.focusNode) {
                        this.collapse(this.focusNode, this.focusOffset);
                        var f = this.getRangeAt(0);
                        d || (d = {}), d.characterOptions = W(d.characterOptions, gb), e = f.move(b, c, d), this.setSingleRange(f)
                    }
                    return e
                }),
                trimStart: O("trimStart"),
                trimEnd: O("trimEnd"),
                trim: O("trim"),
                selectCharacters: L(function(b, c, d, e, f, g) {
                    var h = a.createRange(c);
                    h.selectCharacters(c, d, e, g), this.setSingleRange(h, f)
                }),
                saveCharacterRanges: L(function(a, b, c) {
                    for (var d = this.getAllRanges(), e = d.length, f = [], g = 1 == e && this.isBackward(), h = 0, i = d.length; i > h; ++h) f[h] = {
                        characterRange: d[h].toCharacterRange(b, c),
                        backward: g,
                        characterOptions: c
                    };
                    return f
                }),
                restoreCharacterRanges: L(function(b, c, d) {
                    this.removeAllRanges();
                    for (var e, f, g, h = 0, i = d.length; i > h; ++h) f = d[h], g = f.characterRange, e = a.createRange(c), e.selectCharacters(c, g.start, g.end, f.characterOptions), this.addRange(e, f.backward)
                }),
                text: L(function(a, b) {
                    for (var c = [], d = 0, e = this.rangeCount; e > d; ++d) c[d] = this.getRangeAt(d).text(b);
                    return c.join("")
                })
            }), a.innerText = function(b, c) {
                var d = a.createRange(b);
                d.selectNodeContents(b);
                var e = d.text(c);
                return e
            }, a.createWordIterator = function(a, b, c) {
                var d = C();
                c = h(c, lb);
                var e = d.getPosition(a, b),
                    f = F(e, c.characterOptions, c.wordOptions),
                    g = bb(c.direction);
                return {
                    next: function() {
                        return g ? f.previousStartToken() : f.nextEndToken()
                    },
                    dispose: function() {
                        f.dispose(), this.next = function() {}
                    }
                }
            }, a.noMutation = function(a) {
                var b = C();
                a(b), D()
            }, a.noMutation.createEntryPointFunction = L, a.textRange = {
                isBlockNode: l,
                isCollapsedWhitespaceNode: t,
                createPosition: L(function(a, b, c) {
                    return a.getPosition(b, c)
                })
            }
        }), a
    }(this.rangy)
}, SCAYT.rangy(), function(global) {
    var _$ = window.$,
        _jquip = window.jquip;
    window.$ = window.jquip = function() {
        function a(a, b) {
            for (var c, d = 0, e = Pb.length; e > d; d++) if (Pb[d].apply(this, arguments)) return this;
            return a ? E(a) ? (U ? a() : bb.push(a), this) : F(a) ? this.make(a) : a.nodeType || H(a) ? this.make([a]) : "body" == a && !b && _.body ? (this.context = a.context, this[0] = _.body, this.length = 1, this.selector = a, this) : void 0 !== a.selector ? (this.context = a.context, this.selector = a.selector, this.make(a)) : (a = C(a) && "<" === a.charAt(0) ? (c = pb.exec(a)) ? [_.createElement(c[1])] : N(a).childNodes : k(this.selector = a, b), this.make(a), J(b) && this.attr(b), this) : this
        }
        function b(b, c) {
            return new a(b, c)
        }
        function c(a) {
            return !a || !a.parentNode || 11 == a.parentNode.nodeType
        }
        function d(a, c, d) {
            if (c = c || 0, E(c)) return v(a, function(a, b) {
                return !!c.call(a, b, a) === d
            });
            if (c.nodeType) return v(a, function(a) {
                return a === c === d
            });
            if (C(c)) {
                var e = ":" == c.charAt(0) && b.Expr[c.substring(1)];
                return v(a, function(a) {
                    var b, d = a.parentNode,
                        f = !d;
                    return f && (d = Nb, d.appendChild(a)), b = e ? e(a) : a.parentNode && q(k(c, a.parentNode), a) >= 0, f && d.removeChild(a), b
                })
            }
            return v(a, function(a) {
                return q(c, a) >= 0 === d
            })
        }
        function e(a, b, c) {
            var d = a[Mb];
            return B(c) ? (d || (d = a[Mb] = Rb++), (Sb[d] || (Sb[d] = {}))[b] = c) : d && Sb[d] && (b ? Sb[d][b] : Sb[d])
        }
        function f(a) {
            if (!Tb[a]) {
                var c = b("<" + a + ">").appendTo(_.body),
                    d = b.css && b.css(c[0], "display") || c[0].style.display;
                c.remove(), Tb[a] = d
            }
            return Tb[a]
        }
        function g(a, b) {
            if (a.length = b && b.length || 0, 0 === a.length) return a;
            for (var c = 0, d = b.length; d > c; c++) a[c] = b[c];
            return a
        }
        function h(a, b) {
            b = " " + b + " ";
            for (var c = 0, d = a.length; d > c; c++) if (i(a[c], b)) return !0;
            return !1
        }
        function i(a, b) {
            return 1 === a.nodeType && (" " + a.className + " ").replace(hb, " ").indexOf(b) > -1
        }
        function j(a, b, c) {
            b = b || _, c = c || [], 1 == b.nodeType && a(b) && c.push(b);
            for (var d = b.childNodes, e = 0, f = d.length; f > e; e++) {
                var g = d[e];
                1 == g.nodeType && j(a, g, c)
            }
            return c
        }
        function k(a, c, d) {
            if (a && C(a)) {
                c instanceof b && (c = c[0]), c = c || _, d = d || b.query;
                var e, f = a.substring(1);
                return jb.test(a) && c === _ ? (e = _.getElementById(f)) ? [e] : [] : M(kb.test(a) && c.getElementsByClassName ? c.getElementsByClassName(f) : ib.test(a) ? c.getElementsByTagName(a) : d(a, c))
            }
            return 1 == a.nodeType || 9 == a.nodeType ? [a] : []
        }
        function l(a, b, c) {
            var d, e = _.head || _.getElementsByTagName("head")[0] || ab,
                f = _.createElement("script");
            c && (f.async = "async"), f.onreadystatechange = function() {
                (d = f.readyState) && "loaded" != d && "complete" != d || (f.onload = f.onreadystatechange = null, e && f.parentNode && e.removeChild(f), f = void 0, b && b())
            }, f.onload = b, f.src = a, e.insertBefore(f, e.firstChild)
        }
        function m() {
            Y.console && Y.console.warn(arguments)
        }
        function n(a, b, c) {
            if (null != a) if (Jb && a.forEach === Jb) a.forEach(b, c);
            else if (a.length === +a.length) {
                for (var d = 0, e = a.length; e > d; d++) if (d in a && b.call(c, a[d], d, a) === Cb) return
            } else for (var f in a) if (Fb.call(a, f) && b.call(c, a[f], f, a) === Cb) return
        }
        function o(a, b) {
            if (a && a.getAttribute && b) {
                var c = a.hasAttribute && a.hasAttribute(b) ? a.getAttribute(b) : a[b];
                return null === c ? void 0 : c
            }
        }
        function p(a, c) {
            return B(a) ? b(c).filter(a) : b(c)
        }
        function q(a, b) {
            if (null == a) return -1;
            var c, d;
            if (Lb && a.indexOf === Lb) return a.indexOf(b);
            for (c = 0, d = a.length; d > c; c++) if (a[c] === b) return c;
            return -1
        }
        function r(a, b, c) {
            var d = [];
            return null == a ? d : Kb && a.filter === Kb ? a.filter(b, c) : (n(a, function(a, e, f) {
                b.call(c, a, e, f) && (d[d.length] = a)
            }), d)
        }
        function s(a, c, d) {
            for (var e = [], f = a[c]; f && 9 !== f.nodeType && (void 0 === d || 1 !== f.nodeType || !b(f).is(d));) 1 === f.nodeType && e.push(f), f = f[c];
            return e
        }
        function t(a, b, c) {
            b = b || 1;
            for (var d = 0; a && (1 !== a.nodeType || ++d !== b); a = a[c]);
            return a
        }
        function u(a, b) {
            for (var c = []; a; a = a.nextSibling) 1 === a.nodeType && a !== b && c.push(a);
            return c
        }
        function v(a, b, c) {
            var d, e = [];
            c = !! c;
            for (var f = 0, g = a.length; g > f; f++) d = !! b(a[f], f), c !== d && e.push(a[f]);
            return e
        }
        function w(a, c, d) {
            var e, f, g = [],
                h = 0,
                i = a.length,
                j = a instanceof b || "number" == typeof i && (i > 0 && a[0] && a[i - 1] || 0 === i || F(a));
            if (j) for (; i > h; h++) e = c(a[h], h, d), null != e && (g[g.length] = e);
            else for (f in a) e = c(a[f], f, d), null != e && (g[g.length] = e);
            return g.concat.apply([], g)
        }
        function x(a, b, c) {
            if (!a) return {};
            var d = e(a, b, c);
            return d || y(a)["data-" + b]
        }
        function y(a) {
            var b = {};
            if (1 == a.nodeType) for (var c = 0, d = a.attributes, e = d.length; e > c; c++) b[d.item(c).nodeName] = d.item(c).nodeValue;
            return b
        }
        function z(a, b) {
            return a && b ? a.toLowerCase() === b.toLowerCase() : a == b
        }
        function A(a) {
            return null == a ? String(a) : yb[xb.call(a)] || "object"
        }
        function B(a) {
            return void 0 !== a
        }
        function C(a) {
            return "string" == typeof a
        }
        function D(a) {
            return "object" == typeof a
        }
        function E(a) {
            return "function" == typeof a || "function" === A(a)
        }
        function F(a) {
            return "array" === A(a)
        }
        function G(a) {
            return !C(a) && "number" == typeof a.length
        }
        function H(a) {
            return a && "object" == typeof a && "setInterval" in a
        }
        function I(a) {
            return null == a || !mb.test(a) || isNaN(a)
        }
        function J(a) {
            if (!a || "object" !== A(a) || a.nodeType || H(a)) return !1;
            try {
                if (a.constructor && !Fb.call(a, "constructor") && !Fb.call(a.constructor.prototype, "isPrototypeOf")) return !1
            } catch (b) {
                return !1
            }
            var c;
            for (c in a);
            return void 0 === c || Fb.call(a, c)
        }
        function K(a, b) {
            var c = a.length,
                d = 0;
            if ("number" == typeof b.length) for (var e = b.length; e > d; d++) a[c++] = b[d];
            else for (; void 0 !== b[d];) a[c++] = b[d++];
            return a.length = c, a
        }
        function L() {
            var a, b, c, d, e, f, g = arguments,
                h = g[0] || {},
                i = 1,
                j = g.length,
                k = !1;
            for ("boolean" == typeof h && (k = h, h = g[1] || {}, i = 2), "object" == typeof h || E(h) || (h = {}), j === i && (h = this, --i); j > i; i++) if (null != (a = g[i])) for (b in a) c = h[b], d = a[b], h !== d && (k && d && (J(d) || (e = F(d))) ? (e ? (e = !1, f = c && F(c) ? c : []) : f = c && J(c) ? c : {}, h[b] = L(k, f, d)) : void 0 !== d && (h[b] = d));
            return h
        }
        function M(a, b) {
            var c = b || [];
            if (null != a) {
                var d = A(a);
                null == a.length || "string" == d || "function" == d || "regexp" === d || H(a) ? Hb.call(c, a) : K(c, a)
            }
            return c
        }
        function N(a, b, c) {
            if (b = b || _ || b.ownerDocument || b[0] && b[0].ownerDocument || _, c = c || b.createDocumentFragment(), G(a)) return P(a, b, c) && c;
            for (var d = O(a); d.firstChild;) c.appendChild(d.firstChild);
            return c
        }
        function O(a, b) {
            var c = (b || _).createElement("div"),
                d = (gb.exec(a) || ["", ""])[1].toLowerCase(),
                e = Bb[d] || Bb._default,
                f = e[0];
            for (c.innerHTML = e[1] + a + e[2]; f--;) c = c.lastChild;
            return c
        }
        function P(a, b, c) {
            var d, e, f = [];
            for (d = 0; null != (e = a[d]); d++) C(e) && (e = O(e, b)), e.nodeType ? f.push(e) : f = K(f, e);
            if (c) for (d = 0; d < f.length; d++) f[d].nodeType && c.appendChild(f[d]);
            return f
        }
        function Q(a) {
            if (X && (zb = Ab, a.sort(X), zb)) for (var b = 1; b < a.length; b++) a[b] === a[b - 1] && a.splice(b--, 1);
            return a
        }
        function R() {
            if (!_.body) return null;
            var a = _.createElement("div");
            _.body.appendChild(a), a.style.width = "20px", a.style.padding = "10px";
            var b = a.offsetWidth;
            return _.body.removeChild(a), 40 == b
        }
        function S(a, b) {
            cb.push({
                url: a,
                cb: b
            })
        }
        function T() {
            n(bb, function(a) {
                a()
            }), U = !0
        }
        var U, V, W, X, Y = window,
            Z = "http://cdnjs.cloudflare.com/ajax/libs/sizzle/1.4.4/sizzle.min.js",
            $ = function() {
                return Y.Sizzle || Y.qwery
            },
            _ = document,
            ab = _.documentElement,
            bb = [],
            cb = [],
            db = /Until$/,
            eb = /,/,
            fb = /^(?:parents|prevUntil|prevAll)/,
            gb = /<([\w:]+)/,
            hb = /[\n\t\r]/g,
            ib = /^[\w-]+$/,
            jb = /^#[\w-]+$/,
            kb = /^\.[\w-]+$/,
            lb = /\s+/,
            mb = /\d/,
            nb = /\S/,
            ob = /\r\n/g,
            pb = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
            qb = /\r?\n/g,
            rb = /^(?:select|textarea)/i,
            sb = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
            tb = String.prototype.trim,
            ub = /^\s+/,
            vb = /\s+$/,
            wb = {
                children: !0,
                contents: !0,
                next: !0,
                prev: !0
            },
            xb = Object.prototype.toString,
            yb = {},
            zb = !1,
            Ab = !0,
            Bb = {
                option: [1, "<select multiple='multiple'>", "</select>"],
                legend: [1, "<fieldset>", "</fieldset>"],
                thead: [1, "<table>", "</table>"],
                tr: [2, "<table><tbody>", "</tbody></table>"],
                td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
                col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"],
                area: [1, "<map>", "</map>"],
                _default: [0, "", ""]
            },
            Cb = {},
            Db = Array.prototype,
            Eb = Object.prototype,
            Fb = Eb.hasOwnProperty,
            Gb = Db.slice,
            Hb = Db.push,
            Ib = Db.indexOf,
            Jb = Db.forEach,
            Kb = Db.filter,
            Lb = Db.indexOf,
            Mb = "jq-" + +new Date,
            Nb = _.createElement("p");
        nb.test(" ") && (ub = /^[\s\xA0]+/, vb = /[\s\xA0]+$/);
        var Ob, Pb = [],
            Qb = {},
            Rb = 1,
            Sb = {
                _id: 0
            },
            Tb = {};
        Ob = a.prototype = b.prototype = b.fn = {
            constructor: b,
            selector: "",
            length: 0,
            dm: function(a, b, c) {
                var d, e, f, g, h, i = a[0];
                if (i && this[0]) {
                    if (!(e = (1 === i.nodeType || 3 === i.nodeType) && i) && (d = i && i.parentNode, e = d && 11 === d.nodeType && d.childNodes.length === this.length ? d : N(i), f = e.firstChild, 1 === e.childNodes.length && (e = f), !f)) return this;
                    for (h = 0, g = this.length; g > h; h++) c.call(this[h], 0 == h ? e : e.cloneNode(!0))
                }
                return this
            },
            ps: function(a, b, c) {
                var d = this.constructor();
                return F(a) ? Hb.apply(d, a) : K(d, a), d.prevObject = this, d.context = this.context, "find" === b ? d.selector = this.selector + (this.selector ? " " : "") + c : b && (d.selector = this.selector + "." + b + "(" + c + ")"), d
            }
        }, Ob.make = function(a) {
            return g(this, a), this
        }, Ob.toArray = function() {
            return Gb.call(this, 0)
        }, Ob.get = function(a) {
            return B(a) ? 0 > a ? this[this.length + a] : this[a] : this.toArray()
        }, Ob.add = function(a, d) {
            var e = "string" == typeof a ? b(a, d) : M(a && a.nodeType ? [a] : a),
                f = K(this.get(), e);
            return this.ps(c(e[0]) || c(f[0]) ? f : Q(f))
        }, Ob.each = function(a) {
            if (!E(a)) return this;
            for (var b = 0, c = this.length; c > b && a.call(this[b], b, this[b]) !== !1; b++);
            return this
        }, Ob.attr = function(a, b) {
            var c = this[0];
            return C(a) && void 0 === b ? o(c, a) : this.each(function(c) {
                var d = this.nodeType;
                if (3 !== d && 8 !== d && 2 !== d) if (D(a)) for (var e in a) null === b ? this.removeAttribute(a) : this.setAttribute(e, a[e]);
                else this.setAttribute(a, E(b) ? b.call(this, c, this.getAttribute(a)) : b)
            })
        }, Ob.removeAttr = function(a) {
            return this.each(function() {
                1 == this.nodeType && this.removeAttribute(a)
            })
        }, Ob.data = function(a, b) {
            return void 0 === b ? x(this[0], a) : this.each(function() {
                x(this, a, b)
            })
        }, Ob.append = function() {
            return this.dm(arguments, !0, function(a) {
                1 === this.nodeType && this.appendChild(a)
            })
        }, Ob.prepend = function() {
            return this.dm(arguments, !0, function(a) {
                1 === this.nodeType && this.insertBefore(a, this.firstChild)
            })
        }, Ob.before = function() {
            return this[0] && this[0].parentNode ? this.dm(arguments, !1, function(a) {
                this.parentNode.insertBefore(a, this)
            }) : this
        }, Ob.after = function() {
            return this[0] && this[0].parentNode ? this.dm(arguments, !1, function(a) {
                this.parentNode.insertBefore(a, this.nextSibling)
            }) : this
        }, Ob.replaceWith = function(a) {
            var c = this,
                d = E(a);
            return this.each(function(e) {
                var f = this.nextSibling,
                    g = this.parentNode,
                    h = d ? a.call(this, e, this) : a;
                g && 11 != g.nodeType ? (g.removeChild(this), f ? b(f).before(h) : b(g).append(h)) : c[e] = b(h).clone()[0]
            })
        }, Ob.hide = function() {
            return this.each(function() {
                "none" != this.style.display && (e(this, "display", this.style.display), this.style.display = "none")
            })
        }, Ob.show = function() {
            return this.each(function() {
                this.style.display = e(this, "display") || f(this.tagName)
            })
        }, Ob.toggle = function() {
            return this.each(function() {
                var a = b(this);
                b.Expr.hidden(this) ? a.show() : a.hide()
            })
        }, Ob.eq = function(a) {
            return -1 === a ? this.slice(a) : this.slice(a, +a + 1)
        }, Ob.first = function() {
            return this.eq(0)
        }, Ob.last = function() {
            return this.eq(-1)
        }, Ob.slice = function() {
            return this.ps(Gb.apply(this, arguments), "slice", Gb.call(arguments).join(","))
        }, Ob.map = function(a) {
            return this.ps(w(this, function(b, c) {
                return a.call(b, c, b)
            }))
        }, Ob.find = function(a) {
            var c, d, e = this;
            if (!C(a)) return b(a).filter(function() {
                for (c = 0, d = e.length; d > c; c++) if (W(e[c], this)) return !0
            });
            var f, g, h, i = this.ps("", "find", a);
            for (c = 0, d = this.length; d > c; c++) if (f = i.length, K(i, b(a, this[c])), 0 === c) for (g = f; g < i.length; g++) for (h = 0; f > h; h++) if (i[h] === i[g]) {
                i.splice(g--, 1);
                break
            }
            return i
        }, Ob.not = function(a) {
            return this.ps(d(this, a, !1), "not", a)
        }, Ob.filter = function(a) {
            return this.ps(d(this, a, !0), "filter", a)
        }, Ob.indexOf = function(a) {
            return q(this, a)
        }, Ob.is = function(a) {
            return this.length > 0 && b(this[0]).filter(a).length > 0
        }, Ob.remove = function() {
            for (var a, b = 0; B(a = this[b]); b++) a.parentNode && a.parentNode.removeChild(a);
            return this
        }, Ob.closest = function(a, b) {
            var c, d, e, f = [];
            for (c = 0, d = this.length; d > c; c++) for (e = this[c]; e;) {
                if (p(a, [e]).length > 0) {
                    f.push(e);
                    break
                }
                if (e = e.parentNode, !e || !e.ownerDocument || e === b || 11 === e.nodeType) break
            }
            return f = f.length > 1 ? Q(f) : f, this.ps(f, "closest", a)
        }, Ob.val = function(a) {
            return B(a) ? this.each(function() {
                this.value = a
            }) : this[0] && this[0].value || ""
        }, Ob.html = function(a) {
            return B(a) ? C(a) ? this.each(function() {
                this.innerHTML = a
            }) : this.empty().append(a) : this[0] && this[0].innerHTML || ""
        }, Ob.text = function(a) {
            var b, c = this[0];
            return B(a) ? this.empty().append((c && c.ownerDocument || _).createTextNode(a)) : c && (b = c.nodeType) ? 1 === b || 9 === b ? C(c.textContent) ? c.textContent : c.innerText.replace(ob, "") : 3 === b || 4 === b ? c.nodeValue : null : null
        }, Ob.empty = function() {
            var a, b;
            for (a = 0; B(b = this[a]); a++) for (; b.firstChild;) b.removeChild(b.firstChild);
            return this
        }, Ob.addClass = function(a) {
            var c, d, e, f, g, h, i;
            if (E(a)) return this.each(function(c) {
                b(this).addClass(a.call(this, c, this.className))
            });
            if (a && C(a)) for (c = a.split(lb), d = 0, e = this.length; e > d; d++) if (f = this[d], f && 1 === f.nodeType) if (f.className || 1 !== c.length) {
                for (g = " " + f.className + " ", h = 0, i = c.length; i > h; h++)~g.indexOf(" " + c[h] + " ") || (g += c[h] + " ");
                f.className = V(g)
            } else f.className = a;
            return this
        }, Ob.removeClass = function(a) {
            var c, d, e, f, g, h, i;
            if (E(a)) return this.each(function(c) {
                b(this).removeClass(a.call(this, c, this.className))
            });
            if (a && C(a) || void 0 === a) for (c = (a || "").split(lb), d = 0, e = this.length; e > d; d++) if (f = this[d], 1 === f.nodeType && f.className) if (a) {
                for (g = (" " + f.className + " ").replace(hb, " "), h = 0, i = c.length; i > h; h++) g = g.replace(" " + c[h] + " ", " ");
                f.className = V(g)
            } else f.className = "";
            return this
        }, Ob.hasClass = function(a) {
            return h(this, a)
        }, Ob.fadeIn = function() {
            this.each(function() {
                b(this).show()
            })
        }, Ob.fadeOut = function() {
            this.each(function() {
                b(this).hide()
            })
        }, Ob.serializeArray = function() {
            return this.map(function() {
                return this.elements ? M(this.elements) : this
            }).filter(function() {
                return this.name && !this.disabled && (this.checked || rb.test(this.nodeName) || sb.test(this.type))
            }).map(function(a, c) {
                var d = b(this).val();
                return null == d || F(d) ? w(d, function(a) {
                    return {
                        name: c.name,
                        value: a.replace(qb, "\r\n")
                    }
                }) : {
                    name: c.name,
                    value: d.replace(qb, "\r\n")
                }
            }).get()
        }, Ob.wrap = function(a) {
            return this.each(function() {
                var c = b(b(a)[0].cloneNode(!1));
                b(this).before(c), c.append(b(this))
            })
        }, Ob.prop = function(a, b) {
            return B(b) ? this.each(function() {
                this[a] = b
            }) : this[0] && this[0][a]
        }, Ob.clone = function() {
            return b(this.map(function() {
                return this.cloneNode(!0)
            }))
        }, Ob.toggleClass = function(a, c) {
            return this.each(function() {
                var d = b(this);
                (B(c) ? c : !d.hasClass(a)) ? d.addClass(a) : d.removeClass(a)
            })
        }, b.Expr = {
            hidden: function(a) {
                return "none" === (b.css && b.css(a, "display") || a.style.display)
            },
            visible: function(a) {
                return !b.Expr.hidden(a)
            }
        }, b.hasClass = h, b.walk = j, b.$$ = k, b.setQuery = function(a) {
            b.query = function(b, c) {
                return k(b, c, a ||
                    function(a, b) {
                        return b.querySelectorAll(a)
                    })
            }
        };
        var Ub = $();
        b.setQuery(Ub ||
            function(a, b) {
                return (b = b || _).querySelectorAll ? M(b.querySelectorAll(a)) : []
            }), b.loadScript = l, b.each = function(a, b, c) {
            var d, e = 0,
                f = a.length,
                g = void 0 === f || E(a);
            if (c) if (g) {
                for (d in a) if (b.apply(a[d], c) === !1) break
            } else for (; f > e && b.apply(a[e++], c) !== !1;);
            else if (g) {
                for (d in a) if (b.call(a[d], d, a[d]) === !1) break
            } else for (; f > e && b.call(a[e], e, a[e++]) !== !1;);
            return a
        }, b._each = n, b.filter = p, b._indexOf = q, b._defaults = function(a) {
            return n(Gb.call(arguments, 1), function(b) {
                for (var c in b) null == a[c] && (a[c] = b[c])
            }), a
        }, b._filter = r, b.proxy = function(a, b) {
            if ("string" == typeof b) {
                var c = a[b];
                b = a, a = c
            }
            if (E(a)) {
                var d = Gb.call(arguments, 2),
                    e = function() {
                        return a.apply(b, d.concat(Gb.call(arguments)))
                    };
                return e.guid = a.guid = a.guid || e.guid || Rb++, e
            }
        }, b.dir = s, b.nth = t, b.sibling = u, b.grep = v, b.map = w, b.data = x, b.attrs = y, b.eqSI = z, V = tb ?
            function(a) {
                return null == a ? "" : tb.call(a)
            } : function(a) {
            return null == a ? "" : a.toString().replace(ub, "").replace(vb, "")
        }, b.trim = V, b.indexOf = b.inArray = function(a, b) {
            if (!b) return -1;
            if (Ib) return Ib.call(b, a);
            for (var c = 0, d = b.length; d > c; c++) if (b[c] === a) return c;
            return -1
        }, n("Boolean Number String Function Array Date RegExp Object".split(" "), function(a) {
            return yb["[object " + a + "]"] = a.toLowerCase(), this
        }), b.type = A, b.isFunction = E, b.isArray = Array.isArray || F, b.isWindow = H, b.isNaN = I, b.merge = K, b.extend = b.fn.extend = L, b.makeArray = M, b.htmlFrag = N;
        var Vb = function(a, b, c) {
            if (a === b) return c;
            for (var d = a.nextSibling; d;) {
                if (d === b) return -1;
                d = d.nextSibling
            }
            return 1
        };
        return W = b.contains = ab.contains ?
            function(a, b) {
                return a !== b && (a.contains ? a.contains(b) : !0)
            } : function() {
            return !1
        }, X = ab.compareDocumentPosition ? (W = function(a, b) {
            return !!(16 & a.compareDocumentPosition(b))
        }) &&
        function(a, b) {
            return a === b ? (zb = !0, 0) : a.compareDocumentPosition && b.compareDocumentPosition ? 4 & a.compareDocumentPosition(b) ? -1 : 1 : a.compareDocumentPosition ? -1 : 1
        } : function(a, b) {
            if (a === b) return zb = !0, 0;
            if (a.sourceIndex && b.sourceIndex) return a.sourceIndex - b.sourceIndex;
            var c, d, e = [],
                f = [],
                g = a.parentNode,
                h = b.parentNode,
                i = g;
            if (g === h) return Vb(a, b);
            if (!g) return -1;
            if (!h) return 1;
            for (; i;) e.unshift(i), i = i.parentNode;
            for (i = h; i;) f.unshift(i), i = i.parentNode;
            c = e.length, d = f.length;
            for (var j = 0; c > j && d > j; j++) if (e[j] !== f[j]) return Vb(e[j], f[j]);
            return j === c ? Vb(a, f[j], -1) : Vb(e[j], b, 1)
        }, b.unique = Q, n({
            parent: function(a) {
                var b = a.parentNode;
                return b && 11 !== b.nodeType ? b : null
            },
            parents: function(a) {
                return s(a, "parentNode")
            },
            parentsUntil: function(a, b, c) {
                return s(a, "parentNode", c)
            },
            next: function(a) {
                return t(a, 2, "nextSibling")
            },
            prev: function(a) {
                return t(a, 2, "previousSibling")
            },
            nextAll: function(a) {
                return s(a, "nextSibling")
            },
            prevAll: function(a) {
                return s(a, "previousSibling")
            },
            nextUntil: function(a, b, c) {
                return s(a, "nextSibling", c)
            },
            prevUntil: function(a, b, c) {
                return s(a, "previousSibling", c)
            },
            siblings: function(a) {
                return u(a.parentNode.firstChild, a)
            },
            children: function(a) {
                return u(a.firstChild)
            },
            contents: function(a) {
                return "iframe" === a.nodeName ? a.contentDocument || a.contentWindow["document "] : M(a.childNodes)
            }
        }, function(a, c) {
            b.fn[c] = function(b, d) {
                var e = w(this, a, b),
                    f = Gb.call(arguments);
                return db.test(c) || (d = b), C(d) && (e = M(p(d, e))), e = this.length > 1 && !wb[c] ? Q(e) : e, (this.length > 1 || eb.test(d)) && fb.test(c) && (e = e.reverse()), this.ps(e, c, f.join(","))
            }
        }), n({
            appendTo: "append",
            prependTo: "prepend",
            insertBefore: "before",
            insertAfter: "after"
        }, function(a, c) {
            b.fn[c] = function(d) {
                var e, f, g, h = [],
                    i = b(d),
                    j = 1 === this.length && this[0].parentNode;
                if (j && 11 === j.nodeType && 1 === j.childNodes.length && 1 === i.length) return i[a](this[0]), this;
                for (e = 0, g = i.length; g > e; e++) f = (e > 0 ? this.clone(!0) : this).get(), b(i[e])[a](f), h = h.concat(f);
                return this.ps(h, c, i.selector)
            }
        }), function() {
            var a = document.createElement("div");
            a.style.display = "none", a.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
            var c = a.getElementsByTagName("a")[0];
            b.support = {
                boxModel: null,
                opacity: /^0.55$/.test(c.style.opacity),
                cssFloat: !! c.style.cssFloat
            };
            var d, e = /(webkit)[ \/]([\w.]+)/,
                f = /(opera)(?:.*version)?[ \/]([\w.]+)/,
                g = /(msie) ([\w.]+)/,
                h = /(mozilla)(?:.*? rv:([\w.]+))?/,
                i = navigator.userAgent.toLowerCase(),
                j = e.exec(i) || f.exec(i) || g.exec(i) || i.indexOf("compatible") < 0 && h.exec(i) || [];
            d = b.browser = {
                version: j[2] || "0"
            }, d[j[1] || ""] = !0
        }(), b.scriptsLoaded = function(a) {
            E(a) && bb.push(a)
        }, b.loadAsync = S, Ub || _.querySelectorAll || S(Z, function() {
            b.setQuery($())
        }), b.init = !1, b.onload = function() {
            if (!b.init) try {
                b.support.boxModel = R();
                var a = 0;
                n(cb, function(b) {
                    a++, l(b.url, function() {
                        try {
                            b.cb && b.cb()
                        } catch (c) {}--a || T()
                    })
                }), b.init = !0, a || T()
            } catch (c) {
                m(c)
            }
        }, _.body && !b.init && setTimeout(b.onload, 1), b.hook = function(a) {
            Pb.push(a)
        }, b.plug = function(a, c) {
            var d = C(a) ? a : a.name;
            if (c = E(a) ? a : c, !E(c)) throw "Plugin fn required";
            d && c && (Qb[d] = c), c(b)
        }, b
    }(), $.plug("ajax", function($) {
        function _xhr() {
            if (null != _xhrf) return _xhrf();
            for (var a = 0, b = xhrs.length; b > a; a++) try {
                var c = xhrs[a],
                    d = c();
                if (null != d) return _xhrf = c, d
            } catch (e) {}
            return function() {}
        }
        function _xhrResp(xhr, dataType) {
            if (dataType = (dataType || xhr.getResponseHeader("Content-Type").split(";")[0]).toLowerCase(), dataType.indexOf("json") >= 0) {
                var j = !1;
                return j = window.JSON ? window.JSON.parse(xhr.responseText) : eval(xhr.responseText)
            }
            return dataType.indexOf("script") >= 0 ? eval(xhr.responseText) : dataType.indexOf("xml") >= 0 ? xhr.responseXML : xhr.responseText
        }
        function ajax(a, b) {
            var c, d = _xhr(),
                e = 0;
            "object" == typeof a ? b = a : b.url = a, b = $._defaults(b, {
                userAgent: "XMLHttpRequest",
                lang: "en",
                type: "GET",
                data: null,
                contentType: "application/x-www-form-urlencoded",
                dataType: null,
                processData: !0,
                headers: {
                    "X-Requested-With": "XMLHttpRequest"
                },
                cache: !0
            }), b.timeout && (c = setTimeout(function() {
                d.abort(), b.timeoutFn && b.timeoutFn(b.url)
            }, b.timeout));
            var f = $(b.context || document),
                g = f;
            d.onreadystatechange = function() {
                if (4 == d.readyState) {
                    if (c && clearTimeout(c), d.status < 300) {
                        var a, h = !0,
                            i = b.dataType || "";
                        try {
                            a = _xhrResp(d, i, b)
                        } catch (j) {
                            h = !1, b.error && b.error(d, d.status, d.statusText), g.trigger(f, "ajaxError", [d, d.statusText, b])
                        }
                        b.success && h && (i.indexOf("json") >= 0 || a) && b.success(a), g.trigger(f, "ajaxSuccess", [d, a, b])
                    } else b.error && b.error(d, d.status, d.statusText), g.trigger(f, "ajaxError", [d, d.statusText, b]);
                    b.complete && b.complete(d, d.statusText), g.trigger(f, "ajaxComplete", [d, b])
                } else b.progress && b.progress(++e)
            };
            var a = b.url,
                h = null,
                i = 1 == b.cache,
                j = "POST" == b.type || "PUT" == b.type;
            b.data && b.processData && "object" == typeof b.data && (h = $.formData(b.data)), !j && h && (a += "?" + h, h = null, i || (a = a + "&_=" + (new Date).getTime())), a = a + "?_=" + (new Date).getTime(), i = null, d.open(b.type, a);
            try {
                for (var k in b.headers) d.setRequestHeader(k, b.headers[k])
            } catch (l) {
                console.log(l)
            }
            j && (b.contentType.indexOf("json") >= 0 && (h = b.data), d.setRequestHeader("Content-Type", b.contentType)), d.send(h)
        }
        var xhrs = [function() {
                return new XMLHttpRequest
            }, function() {
                return new ActiveXObject("Microsoft.XMLHTTP")
            }, function() {
                return new ActiveXObject("MSXML2.XMLHTTP.3.0")
            }, function() {
                return new ActiveXObject("MSXML2.XMLHTTP")
            }],
            _xhrf = null;
        $.xhr = _xhr, $._xhrResp = _xhrResp, $.formData = function(a) {
            var b = [],
                c = /%20/g;
            for (var d in a) b.push(encodeURIComponent(d).replace(c, "+") + "=" + encodeURIComponent(a[d].toString()).replace(c, "+"));
            return b.join("&")
        }, $.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function(a, b) {
            $.fn[b] = function(a) {
                return this.bind(b, a)
            }
        }), $.ajax = ajax, $.getJSON = function(a, b, c, d) {
            $.isFunction(b) && (d = c, c = b, b = null), ajax({
                url: a,
                data: b,
                success: c,
                dataType: "json"
            })
        }, $.get = function(a, b, c, d) {
            $.isFunction(b) && (d = c, c = b, b = null), ajax({
                url: a,
                type: "GET",
                data: b,
                success: c,
                dataType: d || "text/plain"
            })
        }, $.post = function(a, b, c, d) {
            $.isFunction(b) && (d = c, c = b, b = null), ajax({
                url: a,
                type: "POST",
                data: b,
                success: c,
                dataType: d || "text/plain"
            })
        }, $.getScript = function(a, b) {
            return $.get(a, void 0, b, "script")
        }, window.JSON || $.loadAsync("http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js")
    }), $.plug("css", function(a) {
        function b(b, c, e) {
            var f = "width" === c ? b.offsetWidth : b.offsetHeight,
                g = "width" === c ? v : w;
            return f > 0 ? ("border" !== e && a.each(g, function() {
                e || (f -= parseFloat(d(b, "padding" + this)) || 0), "margin" === e ? f += parseFloat(d(b, e + this)) || 0 : f -= parseFloat(d(b, "border" + this + "Width")) || 0
            }), f + "px") : ""
        }
        function c(b, c, d, e) {
            if (b && 3 !== b.nodeType && 8 !== b.nodeType && b.style) {
                var g, h = f(c),
                    i = b.style,
                    j = a.cssHooks[h];
                if (c = a.cssProps[h] || h, void 0 === d) return j && "get" in j && void 0 !== (g = j.get(b, !1, e)) ? g : i[c];
                if (!("number" == typeof d && isNaN(d) || null == d || ("number" != typeof d || a.cssNumber[h] || (d += "px"), j && "set" in j && void 0 === (d = j.set(b, d))))) try {
                    i[c] = d
                } catch (k) {}
            }
        }
        function d(b, c, d) {
            var e, g = f(c),
                h = a.cssHooks[g];
            return c = a.cssProps[g] || g, h && "get" in h && void 0 !== (e = h.get(b, !0, d)) ? e : i ? i(b, c, g) : void 0
        }
        function e(a, b, c) {
            var d, e = {};
            for (var d in b) e[d] = a.style[d], a.style[d] = b[d];
            c.call(a);
            for (d in b) a.style[d] = e[d]
        }
        function f(a) {
            return a.replace(p, x)
        }
        function g(b, c, d, e, f, h) {
            var i = b.length;
            if ("object" == typeof c) {
                for (var j in c) g(b, j, c[j], e, f, d);
                return b
            }
            if (void 0 !== d) {
                e = !h && e && a.isFunction(d);
                for (var k = 0; i > k; k++) f(b[k], c, e ? d.call(b[k], k, f(b[k], c)) : d, h);
                return b
            }
            return i ? f(b[0], c) : void 0
        }
        function h(b) {
            return a.isWindow(b) ? b : 9 === b.nodeType ? b.defaultView || b.parentWindow : !1
        }
        var i, j, k, l = document,
            m = l.documentElement,
            n = /alpha\([^)]*\)/i,
            o = /opacity=([^)]*)/,
            p = /-([a-z])/gi,
            q = /([A-Z])/g,
            r = /^-?\d+(?:px)?$/i,
            s = /^-?\d/,
            t = /^(?:body|html)$/i,
            u = {
                position: "absolute",
                visibility: "hidden",
                display: "block"
            },
            v = ["Left", "Right"],
            w = ["Top", "Bottom"],
            x = function(a, b) {
                return b.toUpperCase()
            };
        a.cssHooks = {
            opacity: {
                get: function(a, b) {
                    if (!b) return a.style.opacity;
                    var c = i(a, "opacity", "opacity");
                    return "" === c ? "1" : c
                }
            }
        }, a._each(["height", "width"], function(c) {
            a.cssHooks[c] = {
                get: function(a, d, f) {
                    var g;
                    return d ? 0 !== a.offsetWidth ? b(a, c, f) : (e(a, u, function() {
                        g = b(a, c, f)
                    }), g) : void 0
                },
                set: function(a, b) {
                    return r.test(b) ? (b = parseFloat(b), b >= 0 ? b + "px" : void 0) : b
                }
            }
        }), a.support.opacity || (a.support.opacity = {
            get: function(a, b) {
                return o.test((b && a.currentStyle ? a.currentStyle.filter : a.style.filter) || "") ? parseFloat(RegExp.$1) / 100 + "" : b ? "1" : ""
            },
            set: function(b, c) {
                var d = b.style;
                d.zoom = 1;
                var e = a.isNaN(c) ? "" : "alpha(opacity=" + 100 * c + ")",
                    f = d.filter || "";
                d.filter = n.test(f) ? f.replace(n, e) : d.filter + " " + e
            }
        }), l.defaultView && l.defaultView.getComputedStyle && (j = function(b, c, d) {
            var e, f, g;
            return d = d.replace(q, "-$1").toLowerCase(), (f = b.ownerDocument.defaultView) ? ((g = f.getComputedStyle(b, null)) && (e = g.getPropertyValue(d), "" !== e || a.contains(b.ownerDocument.documentElement, b) || (e = a.style(b, d))), e) : void 0
        }), l.documentElement.currentStyle && (k = function(a, b) {
            var c, d = a.currentStyle && a.currentStyle[b],
                e = a.runtimeStyle && a.runtimeStyle[b],
                f = a.style;
            return !r.test(d) && s.test(d) && (c = f.left, e && (a.runtimeStyle.left = a.currentStyle.left), f.left = "fontSize" === b ? "1em" : d || 0, d = f.pixelLeft + "px", f.left = c, e && (a.runtimeStyle.left = e)), "" === d ? "auto" : d
        }), i = j || k, a.fn.css = function(a, b) {
            return 2 === arguments.length && void 0 === b ? this : g(this, a, b, !0, function(a, b, e) {
                return void 0 !== e ? c(a, b, e) : d(a, b)
            })
        }, a.cssNumber = {
            zIndex: !0,
            fontWeight: !0,
            opacity: !0,
            zoom: !0,
            lineHeight: !0
        }, a.cssProps = {
            "float": a.support.cssFloat ? "cssFloat" : "styleFloat"
        }, a.style = c, a.css = d, a.swap = e, a.camelCase = f;
        var y, z, A, B, C, D, E = function() {
                if (!y) {
                    var b, c, e, f = l.body,
                        g = l.createElement("div"),
                        h = parseFloat(d(f, "marginTop")) || 0,
                        i = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
                    a.extend(g.style, {
                        position: "absolute",
                        top: 0,
                        left: 0,
                        margin: 0,
                        border: 0,
                        width: "1px",
                        height: "1px",
                        visibility: "hidden"
                    }), g.innerHTML = i, f.insertBefore(g, f.firstChild), b = g.firstChild, c = b.firstChild, e = b.nextSibling.firstChild.firstChild, C = 5 !== c.offsetTop, D = 5 === e.offsetTop, c.style.position = "fixed", c.style.top = "20px", B = 20 === c.offsetTop || 15 === c.offsetTop, c.style.position = c.style.top = "", b.style.overflow = "hidden", b.style.position = "relative", A = -5 === c.offsetTop, z = f.offsetTop !== h, f.removeChild(g), y = !0
                }
            },
            F = function(a) {
                var b = a.offsetTop,
                    c = a.offsetLeft;
                return E(), z && (b += parseFloat(d(a, "marginTop")) || 0, c += parseFloat(d(a, "marginLeft")) || 0), {
                    top: b,
                    left: c
                }
            };
        a.fn.offset = function() {
            var b, c = this[0];
            if (!c || !c.ownerDocument) return null;
            if (c === c.ownerDocument.body) return F(c);
            try {
                b = c.getBoundingClientRect()
            } catch (d) {}
            if (!b || !a.contains(m, c)) return b ? {
                top: b.top,
                left: b.left
            } : {
                top: 0,
                left: 0
            };
            var e = l.body,
                f = h(l),
                g = m.clientTop || e.clientTop || 0,
                i = m.clientLeft || e.clientLeft || 0,
                j = f.pageYOffset || a.support.boxModel && m.scrollTop || e.scrollTop,
                k = f.pageXOffset || a.support.boxModel && m.scrollLeft || e.scrollLeft,
                n = b.top + j - g,
                o = b.left + k - i;
            return {
                top: n,
                left: o
            }
        }, a.fn.position = function() {
            if (!this[0]) return null;
            var a = this[0],
                b = this.offsetParent(),
                c = this.offset(),
                e = t.test(b[0].nodeName) ? {
                    top: 0,
                    left: 0
                } : b.offset();
            return c.top -= parseFloat(d(a, "marginTop")) || 0, c.left -= parseFloat(d(a, "marginLeft")) || 0, e.top += parseFloat(d(b[0], "borderTopWidth")) || 0, e.left += parseFloat(d(b[0], "borderLeftWidth")) || 0, {
                top: c.top - e.top,
                left: c.left - e.left
            }
        }, a.fn.offsetParent = function() {
            return this.map(function() {
                for (var a = this.offsetParent || l.body; a && !t.test(a.nodeName) && "static" === d(a, "position");) a = a.offsetParent;
                return a
            })
        }, a._each(["Height", "Width"], function(b) {
            var c = b.toLowerCase();
            a.fn["inner" + b] = function() {
                var a = this[0];
                return a && a.style ? parseFloat(d(a, c, "padding")) : null
            }, a.fn["outer" + b] = function(a) {
                var b = this[0];
                return b && b.style ? parseFloat(d(b, c, a ? "margin" : "border")) : null
            }, a.fn[c] = function(e) {
                var f = this[0];
                if (!f) return null == e ? null : this;
                if (a.isFunction(e)) return this.each(function(b) {
                    var d = a(this);
                    d[c](e.call(this, b, d[c]()))
                });
                if (a.isWindow(f)) {
                    var g = f.document.documentElement["client" + b],
                        h = f.document.body;
                    return "CSS1Compat" === f.document.compatMode && g || h && h["client" + b] || g
                }
                if (9 === f.nodeType) return Math.max(f.documentElement["client" + b], f.body["scroll" + b], f.documentElement["scroll" + b], f.body["offset" + b], f.documentElement["offset" + b]);
                if (void 0 === e) {
                    var i = d(f, c),
                        j = parseFloat(i);
                    return a.isNaN(j) ? i : j
                }
                return this.css(c, "string" == typeof e ? e : e + "px")
            }
        }), a._each(["Left", "Top"], function(b, c) {
            var d = "scroll" + b;
            a.fn[d] = function(b) {
                var e, f;
                return void 0 === b ? (e = this[0]) ? (f = h(e), f ? "pageXOffset" in f ? f[c ? "pageYOffset" : "pageXOffset"] : a.support.boxModel && f.document.documentElement[d] || f.document.body[d] : e[d]) : null : this.each(function() {
                    f = h(this), f ? f.scrollTo(c ? a(f).scrollLeft() : b, c ? b : a(f).scrollTop()) : this[d] = b
                })
            }
        })
    }), $.plug("custom", function(a) {
        for (var b = window, c = {}, d = b.location.search.substring(1).split("&"), e = a.Key = function(a) {
            this.keyCode = a
        }, f = 0; f < d.length; f++) {
            var g = d[f].split("=");
            c[g[0]] = unescape(g[1])
        }
        a.queryString = function(a) {
            return c[a]
        }, e.namedKeys = {
            Backspace: 8,
            Tab: 9,
            Enter: 13,
            Shift: 16,
            Ctrl: 17,
            Alt: 18,
            Pause: 19,
            Capslock: 20,
            Escape: 27,
            PageUp: 33,
            PageDown: 34,
            End: 35,
            Home: 36,
            LeftArrow: 37,
            UpArrow: 38,
            RightArrow: 39,
            DownArrow: 40,
            Insert: 45,
            Delete: 46
        }, a._each(e.namedKeys, function(a, b) {
            var c = a;
            e.prototype["is" + b] = function() {
                return this.keyCode === c
            }
        }), a.key = function(a) {
            return a = a || window.event, new e(a.keyCode || a.which)
        }, a.cancelEvent = function(a) {
            return a || (a = window.event), a.cancelBubble = !0, a.returnValue = !1, a.stopPropagation && (a.stopPropagation(), a.preventDefault()), !1
        }, a.templateSettings = {
            evaluate: /<%([\s\S]+?)%>/g,
            interpolate: /<%=([\s\S]+?)%>/g,
            escape: /<%-([\s\S]+?)%>/g
        }, a._template = function(b, c) {
            var d = a.templateSettings,
                e = "var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('" + b.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(d.escape, function(a, b) {
                        return "',_.escape(" + b.replace(/\\'/g, "'") + "),'"
                    }).replace(d.interpolate, function(a, b) {
                        return "'," + b.replace(/\\'/g, "'") + ",'"
                    }).replace(d.evaluate || null, function(a, b) {
                        return "');" + b.replace(/\\'/g, "'").replace(/[\r\n\t]/g, " ") + ";__p.push('"
                    }).replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace(/\t/g, "\\t") + "');}return __p.join('');",
                f = new Function("obj", "$", e);
            return c ? f(c, a) : function(b) {
                return f(b, a)
            }
        }
    }), $.plug("docready", function(a) {
        function b() {
            if (!i) {
                try {
                    g.documentElement.doScroll("left")
                } catch (a) {
                    return void setTimeout(b, 1)
                }
                c()
            }
        }
        function c(b) {
            if (b === !0 && j--, !j || b !== !0 && !i) {
                if (!g.body) return setTimeout(e, 1);
                if (i = !0, b !== !0 && --j > 0) return;
                if (h) {
                    var c, d = 0,
                        e = h;
                    for (h = null; c = e[d++];) c.call(g, a);
                    a.fn.trigger && a(g).trigger("ready").unbind("ready")
                }
            }
        }
        var d, e, f = window,
            g = document,
            h = [],
            i = !1,
            j = 1;
        a.hook(function(a) {
            return "function" == typeof a ? (this.ready(a), !0) : void 0
        }), a.ready = c, d = g.addEventListener ?
            function() {
                g.removeEventListener("DOMContentLoaded", d, !1), c()
            } : function() {
            "complete" === g.readyState && (g.detachEvent("onreadystatechange", d), c())
        }, a.bindReady = function() {
            if (!e) {
                if (e = !0, "complete" === g.readyState) return setTimeout(c, 1);
                if (g.addEventListener) g.addEventListener("DOMContentLoaded", d, !1), f.addEventListener("load", c, !1);
                else if (g.attachEvent) {
                    g.attachEvent("onreadystatechange", d), f.attachEvent("onload", c);
                    var a = !1;
                    try {
                        a = null == window.frameElement
                    } catch (h) {}
                    g.documentElement.doScroll && a && b()
                }
            }
        }, a.fn.ready = function(b) {
            return a.bindReady(), i ? b.call(g, a) : h && h.push(b), this
        }, a.init || a(document).ready(a.onload)
    }), $.plug("events", function(a) {
        function b(a) {
            return a._jquid || (a._jquid = m++)
        }
        function c(a, b, c) {
            a.addEventListener ? a.addEventListener(b, c, !1) : (n[b + c] = function() {
                c(window.event)
            }, a.attachEvent("on" + b, n[b + c]))
        }
        function d(a, b, c) {
            a.removeEventListener ? a.removeEventListener(b, c, !1) : (a.detachEvent("on" + b, n[b + c]), n[b + c] = null)
        }
        function e(a) {
            var b = ("" + a).split(".");
            return {
                e: b[0],
                ns: b.slice(1).sort().join(" ")
            }
        }
        function f(a) {
            return new RegExp("(?:^| )" + a.replace(" ", " .* ?") + "(?: |$)")
        }
        function g(c, d, g, h) {
            if (d = e(d), d.ns) var i = f(d.ns);
            return a._filter(l[b(c)] || [], function(a) {
                return !(!a || d.e && a.e != d.e || d.ns && !i.test(a.ns) || g && a.fn != g || h && a.sel != h)
            })
        }
        function h(d, f, g, h, i) {
            var j = b(d),
                k = l[j] || (l[j] = []);
            a._each(f.split(/\s/), function(b) {
                var f = a.extend(e(b), {
                    fn: g,
                    sel: h,
                    del: i,
                    i: k.length
                });
                k.push(f), c(d, f.e, i || g)
            }), d = null
        }
        function i(c, e, f, h) {
            var i = b(c);
            a._each((e || "").split(/\s/), function(b) {
                a._each(g(c, b, f, h), function(a) {
                    delete l[i][a.i], d(c, a.e, a.del || a.fn)
                })
            })
        }
        function j(b) {
            var c = a.extend({
                originalEvent: b
            }, b);
            return a._each(o, function(a) {
                b[a] && (c[a] = function() {
                    return b[a].apply(b, arguments)
                })
            }), c
        }
        var k = document,
            l = {},
            m = 1,
            n = {};
        a.bind = c, a.unbind = d;
        var o = ["preventDefault", "stopImmediatePropagation", "stopPropagation"],
            p = a.fn;
        a._each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function(a) {
            p[a] = function(b, c) {
                return arguments.length > 0 ? this.bind(a, b, c) : this.trigger(a)
            }
        }), p.bind = function(a, b) {
            return this.each(function() {
                h(this, a, b)
            })
        }, p.unbind = function(a, b) {
            return this.each(function() {
                i(this, a, b)
            })
        }, p.one = function(a, b) {
            return this.each(function() {
                var c = this;
                h(this, a, function() {
                    b.apply(c, arguments), i(c, a, arguments.callee)
                })
            })
        }, p.delegate = function(b, c, d) {
            return this.each(function(e, f) {
                h(f, c, d, b, function(c) {
                    for (var e = c.target || c.srcElement, g = a.$$(b, f); e && a._indexOf(g, e) < 0;) e = e.parentNode;
                    e && e !== f && e !== document && d.call(e, a.extend(j(c || window.event), {
                        currentTarget: e,
                        liveFired: f
                    }))
                })
            })
        }, p.undelegate = function(a, b, c) {
            return this.each(function() {
                i(this, b, c, a)
            })
        }, p.live = function(b, c) {
            return a(k.body).delegate(this.selector, b, c), this
        }, p.die = function(b, c) {
            return a(k.body).undelegate(this.selector, b, c), this
        }, p.on = function(a, b, c) {
            return "function" == typeof b ? this.bind(a, b) : this.delegate(b, a, c)
        }, p.off = function(a, b, c) {
            return "string" == typeof b ? this.undelegate(b, a, c) : this.unbind(a, c)
        }, p.trigger = function(a) {
            return this.each(function() {
                if ("click" == a && this[a]) return this[a]();
                if (k.createEvent) {
                    var b = k.createEvent("Events");
                    this.dispatchEvent(b, b.initEvent(a, !0, !0))
                } else if (this.fireEvent) try {
                    "ready" !== a && this.fireEvent("on" + a)
                } catch (b) {}
            })
        }, a.init || a(window).bind("load", a.onload)
    }), global.jquip = window.jquip || jquip, window.$ = _$, window.jquip = _jquip
}(SCAYT), function(a) {
    "use strict";
    if (!a.DictionaryManager) {
        var b = function(a, c) {
            this.name = a, this.async = !0, this.sandbox = c, this.userDictionaryManager = new b.UserDictionaryManager(this.sandbox)
        };
        b.wordStatus = {
            unknown: 0,
            misspelled: 1,
            ignored: 2,
            inprocess: 3,
            correct: 4,
            userDictionary: 5,
            userIgnore: 6
        }, b.prototype = {
            init: function() {
                this.sandbox.subscribe("wordsCollected", function(a) {
                    this.wordsCollectedHandler(a.wordsCollection)
                }, this), this.sandbox.subscribe("getUserDictionaryName", function(a) {
                    this.userDictionaryManager.getUserDictionaryName(a)
                }), this.sandbox.subscribe("getUserDictionary", function(a) {
                    this.userDictionaryManager.getUserDictionary(a)
                }), this.sandbox.subscribe("createUserDictionary", function(a) {
                    this.userDictionaryManager.createUserDictionary(a)
                }), this.sandbox.subscribe("restoreUserDictionary", function(a) {
                    this.userDictionaryManager.restoreUserDictionary(a)
                }), this.sandbox.subscribe("renameUserDictionary", function(a) {
                    this.userDictionaryManager.renameUserDictionary(a)
                }), this.sandbox.subscribe("removeUserDictionary", function(a) {
                    this.userDictionaryManager.removeUserDictionary(a)
                }), this.sandbox.subscribe("disconnectFromUserDictionary", function(a) {
                    this.userDictionaryManager.disconnectFromUserDictionary(a)
                }), this.sandbox.subscribe("setUserDictionaryName", function(a) {
                    this.userDictionaryManager.setUserDictionaryName(a.name)
                }), this.sandbox.subscribe("userDictionaryChanged", function() {
                    this.userDictionaryManager.setUserDictionaryNameFromStorage()
                }), this.sandbox.subscribe("userDictionaryStateChanged", function() {
                    this.userDictionaryStateChangedHandler()
                }), this.sandbox.subscribe("userDictionaryStateRestored", function() {
                    this.userDictionaryStateRestoredHandler()
                }), this.sandbox.subscribe("addWordToUserDictionary", function(a) {
                    this.addWordToUserDictionaryHandler(a)
                }), this.sandbox.subscribe("deleteWordFromUserDictionary", function(a) {
                    this.userDictionaryManager.deleteWordFromUserDictionary(a)
                }), this.sandbox.subscribe("getSuggestionsList", function(a) {
                    this.getSuggestionsListHandler(a.word, a.lang)
                }, this), this.getLangList()
            },
            getLangList: function() {
                var a = this;
                a.sandbox.IO.get(new a.sandbox.IO.URL({
                    protocol: a.sandbox.getOption("service_protocol"),
                    host: a.sandbox.getOption("service_host"),
                    port: a.sandbox.getOption("service_port"),
                    path: a.sandbox.getOption("service_path")
                }).addParameter("cmd", "get_lang_list").addParameter("customerid", a.sandbox.getOption("customer_id")), function(b) {
                    var c, d, e;
                    a.sandbox.setOption("scaytLangList", b.langList), c = a.sandbox.getOption("scaytLangList"), d = a.sandbox.getOption("graytLangList"), e = a.sandbox.getOption("lang"), e in c.ltr || e in c.rtl || a.sandbox.setOption("lang", a.sandbox.getDefaultOption("lang")), a.sandbox.fire("moduleReady", {
                        moduleID: a.name
                    })
                }, function() {
                    a.sandbox.setPaused(!0), a.sandbox.removeAllDeferredFunctions()
                })
            },
            wordsCollectedHandler: function(a) {
                var b, c;
                for (var d in a.detectedLanguages) b = this.addWordsToDictionary(a.words, d), c = this.getUnknownWords(d), this.getWordsInfo(c, d), this.precessIgnoredWords(b.ignored, d), "th_TH" == d ? this.processWithTimeout(this.getMisspelledWords(d), d) : this.processWithTimeout(b.misspelled, d)
            },
            userDictionaryStateChangedHandler: function() {
                for (var a = (this.Dictionary, this.getUdWordsFromDictionary()), c = 0; c < a.length; c++) a[c].setStatusForAllInstances(b.wordStatus.unknown);
                this.sandbox.fire("startSpellCheck")
            },
            addWordToUserDictionaryHandler: function(a) {
                var b, c = this.sandbox.getOption("data_attribute_name");
                b = a.scaytNode ? a.scaytNode : this.sandbox.getScaytNodeFromSelection(), a.word ? this.userDictionaryManager.addWordToUserDictionary(a) : b && (a.word = b.getAttribute(c), this.userDictionaryManager.addWordToUserDictionary(a)), this.sandbox.fireInAllApps("removeMarkupFromWords", {
                    words: [{
                        word: a.word
                    }]
                })
            },
            getSuggestionsListHandler: function(a, b) {
                this.sandbox.fire("suggestionListSend", {
                    suggestionList: this.getWordFromDictionary(a, b).suggestions
                })
            },
            userDictionaryStateRestoredHandler: function() {
                for (var a, c = this, d = this.getUdWordsFromDictionary(), e = this.sandbox.getOption("userDictionaryName"), f = b.Dictionary, g = 0; g < d.length; g++) d[g].setStatusForAllInstances(b.wordStatus.unknown);
                this.userDictionaryManager.getUserDictionaryFromServer(e, function(d) {
                    for (var e = d.wordlist, g = 0, h = e.length; h > g; g++) if (a = f.getAllWordsByName(e[g]), a.length > 0) for (var i = 0; i < a.length; i++) a[i].setStatusForAllInstances(b.wordStatus.unknown);
                    c.sandbox.fireInAllApps("removeMarkupInDocument"), c.sandbox.fireInAllApps("startSpellCheck")
                })
            },
            getWordFromDictionary: function(a, c) {
                var d = b.Dictionary;
                return d.getWord(a, c)
            },
            addWordsToDictionary: function(a, c) {
                var d = b.Dictionary,
                    e = this.sandbox.getOption("uid"),
                    f = this.sandbox.getOption("customDictionary") || "",
                    g = {
                        unknown: [],
                        misspelled: [],
                        ignored: []
                    };
                for (var h in a) {
                    var i = a[h].word,
                        j = d.getWord(i, c);
                    j || (j = d.addWord(i, c)), 0 == j.existsInInstance(e) && (j.addToInstance(e), j.addCustomDictionariesInInstance(f, e)), j.getStatus(e) == b.wordStatus.ignored && j.resetStatus(e), this.sandbox.getOption("ignore-all-caps-words") === !0 && j.word.toUpperCase() != j.word.toLowerCase() && j.word == j.word.toUpperCase() && j.setStatus(b.wordStatus.ignored, e), this.sandbox.getOption("ignore-words-with-mixed-cases") === !0 && j.word == j.word.toLowerCase() == 0 && j.word == j.word.toUpperCase() == 0 && (j.word.split("")[0] != j.word.split("")[0].toUpperCase() || j.word.split("").slice(1).join("") != j.word.split("").slice(1).join("").toLowerCase()) && j.setStatus(b.wordStatus.ignored, e), this.sandbox.getOption("ignore-words-with-numbers") === !0 && j.word.replace(/[0-9]/g, "") != j.word && j.setStatus(b.wordStatus.ignored, e), this.sandbox.getOption("ignore-domain-names") === !0 && j.word.replace(/\./g, "") != j.word && j.setStatus(b.wordStatus.ignored, e), j.getStatus(e) === b.wordStatus.inprocess && j.isNeedGetWordInfo(e) && j.setStatus(b.wordStatus.unknown, e), j.getStatus(e) == b.wordStatus.ignored && g.ignored.push(j), j.getStatus(e) == b.wordStatus.unknown && g.unknown.push(j), j.getStatus(e) == b.wordStatus.misspelled && g.misspelled.push(j)
                }
                return g
            },
            getWordsFromDictionaryByStatus: function(a, c) {
                var d = this.sandbox.getOption("uid"),
                    e = b.Dictionary;
                return e.getWordsFromDictionaryByStatus(a, d, c)
            },
            getUnknownWords: function(a) {
                var c = this.getWordsFromDictionaryByStatus(a, b.wordStatus.unknown);
                return c
            },
            getMisspelledWords: function(a) {
                var c = this.getWordsFromDictionaryByStatus(a, b.wordStatus.misspelled);
                return c
            },
            getUdWordsFromDictionary: function() {
                var a = b.Dictionary;
                return a.getAllWordsByStatus(b.wordStatus.userDictionary)
            },
            precessIgnoredWords: function(a, b) {
                var c = this;
                this.sandbox.addDeferredFunction("preocessIgnoredWordsForLang_" + b, {
                    delay: 100,
                    collection: a,
                    partialItemsCount: 100,
                    defferedFunctionArgs: [b],
                    deferredFunction: function(a) {
                        c.sandbox.fire("removeMarkupFromWords", {
                            words: a
                        })
                    }
                })
            },
            processWithTimeout: function(a, c) {
                var d = this;
                this.sandbox.addDeferredFunction("precessWordsForLang_" + c, {
                    delay: 100,
                    collection: a,
                    partialItemsCount: 2,
                    defferedFunctionArgs: [c],
                    deferredFunction: function(a, c) {
                        for (var e = 0; e < a.length;) a[e].getStatus(d.sandbox.getOption("uid")) != b.wordStatus.misspelled ? a.splice(e, 1) : e++;
                        0 !== a.length && d.sandbox.fire("misspelledWordsFound", {
                            words: a,
                            lang: c
                        })
                    }
                })
            },
            getWordsInfo: function(a, c) {
                function d(a, b) {
                    for (var c = 0; c < a.length; c++) a[c].setGlobalStatus(b)
                }
                var e = this,
                    f = "word_",
                    g = this.sandbox.getOption("scaytLangList"),
                    h = (this.sandbox.fire("getWordsLimit").data, this.sandbox.getOption("uid"));
                if (a = a || [], 0 !== a.length) {
                    if ("number" == typeof wordsLimit) {
                        if (0 === wordsLimit) return;
                        a.length = a.length > wordsLimit ? wordsLimit : a.length, this.sandbox.fire("sentWordsCount", {
                            count: a.length
                        })
                    }
                    if (!(c in g.ltr || c in g.rtl)) return void this.sandbox.console.warn('Specified "' + c + '" language is not supported for your Customer ID. More details at http://wiki.webspellchecker.net or contact support@webspellchecker.net');
                    for (var i = 0; i < a.length; i++) a[i].setGlobalStatus(b.wordStatus.inprocess), a[i].setInProcess(h);
                    this.sandbox.addDeferredFunction("getWordsInfoForLang_" + c, {
                        delay: 500,
                        collection: a,
                        partialItemsCount: 10,
                        defferedFunctionArgs: [c],
                        onUnregister: function() {
                            var a = this;
                            d(a.collection, b.wordStatus.unknown)
                        },
                        deferredFunction: function(a, c) {
                            for (var g = [], h = 0; h < a.length; h++) g.push(a[h].word);
                            var i = null == e.sandbox.getOption("userDictionaryName") ? "" : e.sandbox.getOption("userDictionaryName");
                            return e.sandbox.IO.get(new e.sandbox.IO.URL({
                                protocol: e.sandbox.getOption("service_protocol"),
                                host: e.sandbox.getOption("service_host"),
                                port: e.sandbox.getOption("service_port"),
                                path: e.sandbox.getOption("service_path")
                            }).addParameter("cmd", "check_spelling").addParameter("customerid", e.sandbox.getOption("customer_id")).addParameter("format", "json").addParameter("out_type", "words").addParameter("version", "1.0").addParameter("slang", c).addParameter("custom_dictionary", e.sandbox.getOption("customDictionary")).addParameter("user_dictionary", i).addParameter("user_wordlist", e.userDictionaryManager.getWordsFromUserDictionary()).addParameter("text", g.join(",")), function(d) {
                                if ("th_TH" == c) for (var g = 0; g < d.length; g++) {
                                    var h = {};
                                    h[f + d[g].word] = {}, h[f + d[g].word].word = d[g].word, e.addWordsToDictionary(h, c), a.push(b.Dictionary.getWord(d[g].word, c))
                                }
                                for (var i = e.sandbox.getOption("uid"), j = e.sandbox.getOption("customDictionary") || "", k = {}, l = [], g = 0; g < d.length; g++) k[f + d[g].word] = d[g];
                                for (g = 0; g < a.length; g++) {
                                    var m = a[g].word,
                                        n = k[f + m] && "true" == k[f + m].ud;
                                    k[f + m] && !n ? (a[g].setStatusForAllInstancesWithSuchCustomDictionary(b.wordStatus.misspelled, j), a[g].suggestions = k[f + m].suggestions, l.push(a[g])) : n ? a[g].setStatusForAllInstances(b.wordStatus.userDictionary) : j ? a[g].setStatusForAllInstancesWithSuchCustomDictionary(b.wordStatus.correct, j) : a[g].setGlobalStatus(b.wordStatus.correct), a[g].removeFromProcess(i)
                                }
                                0 !== l.length && e.sandbox.fireInAllApps("misspelledWordsFound", {
                                    words: l,
                                    lang: c
                                }), e.sandbox.setOption("numberOfFailedRequest", 0)
                            }, function() {
                                var f = e.sandbox.getOption("uid"),
                                    g = e.sandbox.getOption("numberOfFailedRequest");
                                if (e.sandbox.setOption("numberOfFailedRequest", ++g), g > 4) {
                                    e.sandbox.setPaused(!0), e.sandbox.removeAllDeferredFunctions();
                                    for (var h = 0; h < a.length; h++) a[h].removeFromProcess(f);
                                    d(a, b.wordStatus.unknown)
                                } else e.getWordsInfo(a, c)
                            }), !0
                        }
                    })
                }
            }
        }, b.UserDictionaryManager = function(a) {
            this.sandbox = a, this.init()
        }, b.UserDictionaryManager.prototype = {
            init: function() {
                var a, c, d = [],
                    e = (this.sandbox.getOption("lang"), this.sandbox.getOption("uid"), b.Dictionary),
                    f = e.getAllWordsByStatus(b.wordStatus.userDictionary);
                for (this.userDictionaryName = this.sandbox.getOption("userDictionaryName"), this.userDictionaryKey = this.sandbox.getOption("userDictionaryKey"), this.userDictionaryNameKey = this.sandbox.getOption("userDictionaryNameKey"), c = 0; c < f.length; c++) f[c].setStatusForAllInstances(b.wordStatus.unknown);
                if (!(null != this.userDictionaryName && "string" == typeof this.userDictionaryName && this.userDictionaryName.length > 0)) {
                    try {
                        d = this.sandbox.DataStorage.getData(this.userDictionaryKey), null == d && (d = [], this.sandbox.DataStorage.setData(this.userDictionaryKey, d))
                    } catch (g) {
                        this.sandbox.DataStorage.setData(this.userDictionaryKey, d)
                    }
                    a = this.sandbox.DataStorage.getData(this.userDictionaryNameKey), "string" == typeof a && null != a && a.length > 0 ? (this.userDictionaryName = a, this.sandbox.setOption("userDictionaryName", this.userDictionaryName), this.getUserDictionaryFromServer(a, function(a) {
                        for (var c = a.wordlist, d = 0, g = c.length; g > d; d++) if (f = e.getAllWordsByName(c[d]), f.length > 0) for (var h = 0; h < f.length; h++) f[h].setStatusForAllInstances(b.wordStatus.userDictionary)
                    })) : this.sandbox.DataStorage.setData(this.userDictionaryNameKey, null)
                }
                for (var c = 0, h = d.length; h > c; c++) if (f = e.getAllWordsByName(d[c]), f.length > 0) for (var i = 0; i < f.length; i++) f[i].setStatusForAllInstances(b.wordStatus.userDictionary)
            },
            onSuccessCallback: function(a, b, c) {
                switch ("function" == typeof b.onSuccess && b.onSuccess(c), a) {
                    case "create":
                        this.setUserDictionaryName(c.name), this.sandbox.fireInAllApps("userDictionaryChanged");
                        break;
                    case "delete":
                        this.setUserDictionaryName(null), this.sandbox.fireInAllApps("userDictionaryChanged"), this.sandbox.fire("userDictionaryStateChanged");
                        break;
                    case "rename":
                        return this.setUserDictionaryName(c.name), void this.sandbox.fireInAllApps("userDictionaryChanged");
                    case "check":
                        this.setUserDictionaryName(c.name), this.sandbox.fireInAllApps("userDictionaryChanged"), this.sandbox.fire("userDictionaryStateRestored")
                }
                this.clearUserDictionary()
            },
            onErrorCallback: function(a, b) {
                "function" == typeof a.onError && a.onError(b)
            },
            createUserDictionary: function(a) {
                var b = this,
                    c = "create";
                this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "create").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", a.name).addParameter("wordlist", this.getWordsFromUserDictionary()), function(d) {
                    b.onSuccessCallback(c, a, d)
                }, function(c) {
                    b.onErrorCallback(a, c)
                })
            },
            removeUserDictionary: function(a) {
                var b = this,
                    c = "delete";
                this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "delete").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", this.sandbox.getOption("userDictionaryName")), function(d) {
                    b.onSuccessCallback(c, a, d)
                }, function(c) {
                    b.onErrorCallback(a, c)
                })
            },
            disconnectFromUserDictionary: function() {
                this.setUserDictionaryName(null), this.sandbox.DataStorage.setData(this.userDictionaryKey, []), this.sandbox.fireInAllApps("userDictionaryChanged"), this.sandbox.fire("userDictionaryStateChanged"), this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "delete").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", "").addParameter("remove_ud_cookie", "false"), function() {}, function() {})
            },
            renameUserDictionary: function(a) {
                var b = this,
                    c = "rename";
                this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "rename").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", this.sandbox.getOption("userDictionaryName")).addParameter("new_name", a.newName), function(d) {
                    b.onSuccessCallback(c, a, d)
                }, function(c) {
                    b.onErrorCallback(a, c)
                })
            },
            restoreUserDictionary: function(a) {
                var b = this,
                    c = "check";
                this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "check").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", a.name), function(d) {
                    b.onSuccessCallback(c, a, d)
                }, function(c) {
                    b.onErrorCallback(a, c)
                })
            },
            addWordToUserDictionaryServer: function(a) {
                var b = this;
                this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "addword").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", this.sandbox.getOption("userDictionaryName")).addParameter("word", a.word), function(c) {
                    "function" == typeof a.onSuccess && a.onSuccess(c), b.clearUserDictionary()
                }, function(b) {
                    "function" == typeof a.onError && a.onError(b)
                })
            },
            deleteWordFromUserDictionaryServer: function(a) {
                var b = this;
                this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "deleteword").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", this.sandbox.getOption("userDictionaryName")).addParameter("word", a.word), function(c) {
                    "function" == typeof a.onSuccess && a.onSuccess(c), b.sandbox.fireInAllApps("startSpellCheck")
                }, function(b) {
                    "function" == typeof a.onError && a.onError(b)
                })
            },
            getUserDictionary: function(a) {
                var b = this.sandbox.DataStorage.getData(this.userDictionaryKey);
                null == b && (b = []), this.checkUserDictionaryName(this.sandbox.getOption("userDictionaryName")) ? this.getUserDictionaryFromServer(a.name, a.callback) : "function" == typeof a.callback && a.callback({
                    wordlist: b
                })
            },
            getUserDictionaryFromServer: function(a, b) {
                this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "getdict").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", a || this.sandbox.getOption("userDictionaryName")), function(a) {
                    "function" == typeof b && b(a)
                }, function() {})
            },
            addWordsToUserDictionary: function(a) {
                for (var b = 0; b < a.length; b++) this.addWordToUserDictionary({
                    word: a[b]
                })
            },
            getWordsFromUserDictionary: function() {
                var a = this.sandbox.DataStorage.getData(this.userDictionaryKey);
                return null == a && (a = []), a.join()
            },
            checkUserDictionaryName: function(a) {
                var b;
                return b = "string" == typeof a && null != a && a.length > 0 ? !0 : !1
            },
            setWordStatus: function(a, c) {
                var d, e, f = b.Dictionary,
                    g = f.getDictionary();
                for (var h in g) if (e = f.getWord(a, h)) {
                    switch (c) {
                        case "userDictionary":
                            d = b.wordStatus.userDictionary;
                            break;
                        case "unknown":
                            d = b.wordStatus.unknown;
                            break;
                        default:
                            d = b.wordStatus.unknown
                    }
                    e.setStatusForAllInstances(d)
                }
            },
            addWordToUserDictionary: function(a) {
                var b = this.sandbox.DataStorage.getData(this.userDictionaryKey);
                null == b && (b = []), this.checkUserDictionaryName(this.sandbox.getOption("userDictionaryName")) ? (this.addWordToUserDictionaryServer(a), this.setWordStatus(a.word, "userDictionary")) : this.sandbox.Utils.inArray(b, a.word) || (b.push(a.word), this.sandbox.DataStorage.setData(this.userDictionaryKey, b), this.setWordStatus(a.word, "userDictionary"), "function" == typeof a.onSuccess && a.onSuccess({}))
            },
            deleteWordFromUserDictionary: function(a) {
                var b, c = this.sandbox.DataStorage.getData(this.userDictionaryKey);
                null == c && (c = []), this.checkUserDictionaryName(this.sandbox.getOption("userDictionaryName")) ? (this.deleteWordFromUserDictionaryServer(a), this.setWordStatus(a.word, "unknown")) : (b = this.sandbox.Utils.indexOf(c, a.word), -1 !== b && (c.splice(b, 1), this.sandbox.DataStorage.setData(this.userDictionaryKey, c), this.setWordStatus(a.word, "unknown"), "function" == typeof a.onSuccess && a.onSuccess({}), this.sandbox.fireInAllApps("startSpellCheck")))
            },
            clearUserDictionary: function() {
                this.sandbox.DataStorage.setData(this.userDictionaryKey, []), this.sandbox.IO.get(new this.sandbox.IO.URL({
                    protocol: this.sandbox.getOption("service_protocol"),
                    host: this.sandbox.getOption("service_host"),
                    port: this.sandbox.getOption("service_port"),
                    path: this.sandbox.getOption("service_path")
                }).addParameter("cmd", "user_dictionary").addParameter("action", "delete").addParameter("customerid", this.sandbox.getOption("customer_id")).addParameter("v", "2.1").addParameter("format", "json").addParameter("name", "").addParameter("remove_ud_cookie", "true"), function() {}, function() {})
            },
            setUserDictionaryName: function(a) {
                this.sandbox.DataStorage.setData(this.userDictionaryNameKey, a), this.sandbox.setOption("userDictionaryName", a)
            },
            setUserDictionaryNameFromStorage: function() {
                this.sandbox.setOption("userDictionaryName", this.sandbox.DataStorage.getData(this.userDictionaryNameKey)), this.setUserDictionaryName(this.sandbox.DataStorage.getData(this.userDictionaryNameKey))
            }
        }, b.Dictionary = b.Dictionary ||
            function() {
                var a = {},
                    c = "word_";
                return {
                    getWord: function(b, d) {
                        return a[d] && a[d][c + b]
                    },
                    getWordsFromDictionaryByStatus: function(a, b, c) {
                        var d = [];
                        return this.each(a, function(a) {
                            a.getStatus(b) == c && d.push(a)
                        }), d
                    },
                    getAllWordsByStatus: function(b) {
                        var c = [];
                        for (var d in a) this.each(d, function(a) {
                            a.hasStatusInAnyInstance(b) && c.push(a)
                        });
                        return c
                    },
                    getAllWordsByName: function(b) {
                        var d = [];
                        for (var e in a) a[e][c + b] && d.push(a[e][c + b]);
                        return d
                    },
                    setStatusToWords: function(a, b, c, d) {
                        for (var e = 0; e < a.length; e++) this.getWord(a[e], c) || this.addWord(a[e], c), this.getWord(a[e], c).setStatus(b, d)
                    },
                    getDictionary: function() {
                        var b = {};
                        for (var c in a) a.hasOwnProperty(c) && (b[c] = a[c]);
                        return b
                    },
                    addWord: function(d, e) {
                        var f = new b.Word(d);
                        return a[e] = a[e] || {}, a[e][c + d] = f
                    },
                    each: function(b, c) {
                        if ("function" == typeof c) for (var d in a[b]) c(a[b][d])
                    },
                    clear: function() {
                        a = {}
                    }
                }
            }(), b.Word = function(a) {
            var b, c = {},
                d = {},
                e = {},
                f = {};
            this.word = a, this.suggestions = [], this.getStatus = function(a) {
                var b;
                return "undefined" != typeof c[a] && (b = c[a]), b
            }, this.hasStatusInAnyInstance = function(a) {
                var b = !1;
                if ("undefined" != typeof a) for (var e in d) if (c[e] === a) {
                    b = !0;
                    break
                }
                return b
            }, this.resetStatus = function(a) {
                "undefined" != typeof b && "undefined" != typeof a ? this.setStatus(b, a) : "undefined" != typeof a && this.setStatus(0, a)
            }, this.setGlobalStatus = function(a) {
                if ("undefined" != typeof a) {
                    b = a;
                    for (var e in d)(0 == c[e] || 3 == c[e]) && (c[e] = b)
                }
            }, this.setStatusForAllInstances = function(a) {
                if ("undefined" != typeof a) for (var b in d) c[b] = a
            }, this.setStatusForAllInstancesWithSuchCustomDictionary = function(a, b) {
                if ("undefined" != typeof a) for (var f in d) e[f] === b && (0 == c[f] || 3 == c[f]) && (c[f] = a)
            }, this.setStatus = function(a, b) {
                "undefined" != typeof a && "undefined" != typeof b && (c[b] = a)
            }, this.addCustomDictionariesInInstance = function(a, b) {
                "undefined" != typeof b && (e[b] = a)
            }, this.setInProcess = function(a) {
                "undefined" == typeof a || f[a] || (f[a] = !0)
            }, this.removeFromProcess = function(a) {
                "undefined" != typeof a && f[a] && delete f[a]
            }, this.isNeedGetWordInfo = function(a) {
                if ("undefined" != typeof a) {
                    if (f[a]) return !1;
                    for (var b in f) if (e[b] === e[a]) return !1;
                    return !0
                }
            }, this.addToInstance = function(a) {
                d[a] = this.word, this.resetStatus(a)
            }, this.existsInInstance = function(a) {
                return d[a] ? !0 : !1
            }
        }, a.DictionaryManager = b
    }
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b
    };
    b.prototype = {
        init: function() {
            this.sandbox.subscribe("markupWords", function(a) {
                this.markupWords(a.ranges, a.lang)
            }, this), this.sandbox.subscribe({
                eventType: "keydown",
                element: this.sandbox.getOption("container"),
                handler: this.handleKeydown,
                priority: 1500,
                context: this
            }), this.sandbox.subscribe("removeMarkupInSelectionNode", function(a) {
                this.removeMarkupInSelectionNode(a)
            }, this), this.sandbox.subscribe("removeMarkupInDocument", function() {
                this.removeMarkupInDocument()
            }, this), this.sandbox.subscribe("removeMarkupFromWords", function(a) {
                this.removeMarkupFromWords(a.words)
            }, this), this.sandbox.subscribe("removeMarkup", function(a) {
                a.scayt && this.removeMarkup(a.nodes)
            }, this)
        },
        handleKeydown: function(a) {
            var b, c, d, e, f, g, h, i, j, k, l = this,
                m = this.sandbox.Utils,
                n = 67,
                o = 65,
                p = 90,
                q = 89,
                r = [45],
                s = [8, 106, 107, 109, 110, 111, 187, 186, 188, 190, 191, 192, 219, 220, 221, 222],
                t = [13, 32];
            if (s.push(m.browser.gecko ? 173 : 189), b = (a.ctrlKey || a.metaKey) && a.keyCode === n, c = (a.ctrlKey || a.metaKey) && a.keyCode === o, d = (a.ctrlKey || a.metaKey) && !a.shiftKey && a.keyCode === p, e = (a.ctrlKey || a.metaKey) && a.shiftKey && a.keyCode === p, f = (a.ctrlKey || a.metaKey) && !a.shiftKey && a.keyCode === q, g = !(b || c || d || e || f), h = a.keyCode > 40 && a.keyCode < 91 || a.keyCode >= 96 && a.keyCode <= 105, i = m.indexOf(r, a.keyCode) < 0, j = m.indexOf(s, a.keyCode) >= 0, k = m.indexOf(t, a.keyCode) >= 0, g && h && i || j || k) if (k && this.sandbox.isCaretInEndOfMisspelledWord()) {
                var u = this.getScaytNodeIfCaretInEndOfIt(),
                    v = u ? this.sandbox.isNodeContentBroken(u, this.sandbox.getOption("data_attribute_name")) : !1;
                v ? l.removeMarkupInSelectionNode() : u && l.moveCaretFromScaytNode(u)
            } else l.removeMarkupInSelectionNode()
        },
        moveCaretFromScaytNode: function(a) {
            var b, c, d, e = a,
                f = this.sandbox.getSelection(),
                g = (this.sandbox.Utils.getCurrentDocument(this.sandbox.getOption("documentContainer")), this);
            d = e.parentNode, c = this.sandbox.createRange(), b = document.createTextNode("‌"), d.insertBefore(b, e.nextSibling), c.setStartAfter(b), c.collapse(!0), f.removeAllRanges(), f.addRange(c), setTimeout(function() {
                var a, c = g.sandbox.saveSelection();
                a = g.sandbox.getSavedSelectionParentContainer(c), b.nodeValue = b.nodeValue.replace(/\u200C/, ""), g.sandbox.restoreSelection(c), g.sandbox.Utils.browser.gecko && a && a.normalize()
            }, 0)
        },
        markupWords: function(a, b) {
            if (0 !== a.length) {
                var c = this,
                    d = c.sandbox.getOption("documentContainer"),
                    e = c.sandbox.getOption("misspelled_word_node"),
                    f = c.sandbox.getOption("data_attribute_name"),
                    g = c.sandbox.getOption("data_lang_attribute"),
                    h = c.sandbox.getOption("misspelled_word_class"),
                    i = c.sandbox.Utils.getCurrentDocument(d).createElement(e);
                this.sandbox.UILib.addClass(i, h);
                for (var j = 0; j < a.length; j++) if (a[j].language === b) {
                    var k = a[j].range.commonAncestorContainer(),
                        l = c.sandbox.Utils.isEqualNode(k, f) ? [k] : c.sandbox.DOM.findNodeParents(k, e, f);
                    if (0 === l.length) {
                        var m = i.cloneNode(!0),
                            n = a[j].range.toString();
                        m.setAttribute(f, c.sandbox.Utils.removeSpecialCharacters(n)), b && m.setAttribute(g, b), m.appendChild(a[j].range.extractContents()), a[j].range.insertNode(m);
                        var o = c.sandbox.DOM.findNodeChildren(m, e, f);
                        for (c.sandbox.fire("markupedNode", {
                            node: m
                        }); o.length > 0;) {
                            var p = o.shift();
                            c.removeMarkup(p)
                        }
                    }
                }
            }
        },
        removeMarkupInDocument: function() {
            var a, b = this,
                c = b.sandbox.getOption("container"),
                d = b.sandbox.getOption("misspelled_word_node"),
                e = b.sandbox.getOption("data_attribute_name");
            a = b.sandbox.DOM.query(c, d + "[" + e + "]"), b.removeMarkup(a)
        },
        removeMarkupFromWords: function(a) {
            for (var b, c, d = this, e = d.sandbox.getOption("container"), f = d.sandbox.getOption("misspelled_word_node"), g = d.sandbox.getOption("data_attribute_name"), h = this.sandbox.getOption("data_lang_attribute"), i = [], j = this.sandbox.UILib, k = 0; k < a.length; k++) c = d.sandbox.DOM.query(e, f + "[" + g + '="' + a[k].word + '"]'), b = a[k].lang, b && (c = j.filter(c, "[" + h + '="' + b + '"]')), i.push.apply(i, c);
            d.removeMarkup(i)
        },
        removeMarkupInSelectionNode: function(a) {
            function b(a) {
                var b = [];
                return b = i.arrayFilter.call(a, function(a) {
                    return i.isEqualNode(a, j)
                })
            }
            var c, d, e, f, g, h = this,
                i = this.sandbox.Utils,
                j = (this.sandbox.UILib, h.sandbox.getOption("data_attribute_name")),
                k = a && a.selectionNode,
                l = a && a.removeInside,
                m = a && a.forceBookmark,
                n = h.sandbox.getSelection(),
                o = this.sandbox.getOption("container"),
                p = [];
            k ? (e = h.sandbox.createRange(), e.selectNode(k), p = e.getNodes()) : n.rangeCount() > 0 && (e = n.getRangeAt(0), c = e.startContainer(), d = e.endContainer(), f = e.startOffset(), g = e.endOffset(), p = this.getNeighbourScaytNodes(c, d, f, g), l && (p = p.concat(e.getNodes()))), p = b(p), p = i.arrayUnique(p), m && !this.sandbox.getOption("focused") && p.length > 0 && this.sandbox.fire({
                eventType: "focus",
                element: o
            });
            for (var q = 0, r = p.length; r > q; q += 1) h.removeMarkup(p[q])
        },
        getNeighbourScaytNodes: function(a, b, c, d) {
            function e(a, b, c) {
                {
                    var d, e, f, g, k, n = h.sandbox.getOption("container"),
                        o = /[^\t-\r \u0085\u00A0\u1680\u180E\u2000-\u200B\u2028\u2029\u202F\u205F\u3000]+/g,
                        p = h.sandbox.getOption("punctuationRegExp"),
                        q = h.sandbox.getOption("wordBoundaryRegex"),
                        r = h.sandbox.getOption("blockElementsRegex"),
                        s = /[^ \f\n\r\t\v\u00A0\u1680\u180E\u2000-\u200C\u2028\u2029\u202F\u205F\u3000\uFEFF]/,
                        t = h.sandbox.getOption("backspaceKeyButtonPressed"),
                        u = h.sandbox.getOption("deleteKeyButtonPressed"),
                        v = h.sandbox.getOption("spaceKeyButtonPressed"),
                        w = h.sandbox.getOption("enterKeyButtonPressed");
                    h.sandbox.getSelection().getRangeAt(0).collapsed()
                }
                if (b) {
                    k = new i.Walker(b, c, a, n);
                    do {
                        if (k.siblingNode && r.test(k.siblingNode.nodeName.toLowerCase()) && k.textWalkedThrough.length > 0 && s.test(k.textWalkedThrough)) break;
                        if (i.isEqualNode(k.currentNode, l) && k.textWalkedThrough.length > 0) {
                            d = k.currentNode;
                            break
                        }
                        if (e = k.textWalkedThrough, f = k.textWalkedThrough.replace(new RegExp("[" + p + "]", "g"), " "), g = -1 !== e.search(new RegExp("[" + p + "]")), a || (e = e.split("").reverse().join(""), f = f.split("").reverse().join("")), (v || w) && !a && q.test(e)) {
                            d = j.findNodeParents(k.currentNode, m, l)[0];
                            break
                        }
                        if (u && !a && 0 === e.search(/\s/)) break;
                        if (t && a && 0 === e.search(/\s/)) break;
                        if (g && !u && !t) {
                            d = j.findNodeParents(k.currentNode, m, l)[0];
                            break
                        }
                        if (o.lastIndex = 0, o.test(f) && o.lastIndex + 1 <= e.length) break
                    } while (k.getNext())
                }
                return {
                    scaytNode: d,
                    text: e
                }
            }
            var f, g, h = this,
                i = this.sandbox.Utils,
                j = (this.sandbox.UILib, this.sandbox.DOM),
                k = [],
                l = this.sandbox.getOption("data_attribute_name"),
                m = this.sandbox.getOption("misspelled_word_node"),
                n = h.sandbox.getOption("backspaceKeyButtonPressed"),
                o = h.sandbox.getOption("deleteKeyButtonPressed");
            return f = e(!1, a, c), g = e(!0, b, d), n && /^\s{2,}/.test(f.text) && (f.scaytNode = null, g.scaytNode = null), o && /^\s{2,}/.test(g.text) && (f.scaytNode = null, g.scaytNode = null), (n || o) && /^\s+/.test(f.text) && /^\s+/.test(g.text) && (f.scaytNode = null, g.scaytNode = null), k = k.concat(f.scaytNode, g.scaytNode)
        },
        getScaytNodeIfCaretInEndOfIt: function() {
            var a, b = this.sandbox.getScaytNodeFromSelection(),
                c = this.sandbox.getSelection(),
                d = c.getRangeAt(0).endContainer().childNodes;
            return !b && d.length && (a = d[c.getRangeAt(0).startOffset() - 1], b = 1 === a.nodeType ? a : null), b
        },
        removeMarkup: function(a) {
            var b, c, d, e, f, g = (this.sandbox.Utils.getCurrentDocument(this.sandbox.getOption("documentContainer")), this.sandbox.getOption("focused")),
                h = [].concat(a);
            for (g && h.length > 0 && (b = this.sandbox.saveSelection(), f = this.sandbox.getSavedSelectionParentContainer(b)); h.length > 0;) c = h.shift(), c.innerHTML ? (d = this.sandbox.createRange(), d.selectNode(c), e = d.createContextualFragment(c.innerHTML), d.deleteContents(), d.insertNode(e), this.sandbox.fire("removedMarkupInContainer", {
                node: d.commonAncestorContainer()
            })) : this.sandbox.UILib.remove(c);
            this.sandbox.restoreSelection(b), this.sandbox.Utils.browser.gecko && f && f.normalize()
        }
    }, a.Markup = b
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b
    };
    b.prototype = {
        init: function() {
            this.sandbox.subscribe("startSpellCheck", function() {
                this.startSpellCheck()
            }), this.sandbox.subscribe({
                eventType: "keydown",
                element: this.sandbox.getOption("container"),
                handler: function(a) {
                    this.handleKeydown(a)
                }
            }), this.sandbox.subscribe("collectWords", function(a) {
                this.collectWords(a.source, a.ignoreMisspellingsInContainer)
            }, this)
        },
        handleKeydown: function(a) {
            var b, c = this,
                d = this.sandbox.getOption("multiLanguageMode");
            (32 == a.keyCode || 13 == a.keyCode || 32 == a.charCode || 13 == a.charCode) && c.sandbox.addDeferredFunction("collectWordsAfterKeypress", {
                single: !0,
                delay: 0,
                deferredFunction: function() {
                    var a, b = c.sandbox.getSelection();
                    if (b.rangeCount() > 0) {
                        var e = b.getRangeAt(0);
                        a = d ? e.commonAncestorContainer() : e, c.sandbox.fire("collectWords", {
                            source: a
                        })
                    }
                }
            }), c.sandbox.addDeferredFunction("collectWordsAfterDelay", {
                single: !0,
                delay: 2e3,
                deferredFunction: function() {
                    var a, e = c.sandbox.getOption("container");
                    d ? b = e : (a = c.sandbox.createRange(), a.selectNodeContents(e), b = a), c.sandbox.fire("collectWords", {
                        source: b
                    })
                }
            })
        },
        startSpellCheck: function() {
            var a, b = this.sandbox.createRange(),
                c = this.sandbox.getOption("container"),
                d = this.sandbox.getOption("multiLanguageMode");
            d ? a = c : (b.selectNodeContents(c), a = b.toString()), this.sandbox.fire("collectWords", {
                source: a,
                ignoreMisspellingsInContainer: !1
            })
        },
        collectWords: function(a, b) {
            var c;
            switch (typeof a) {
                case "string":
                    c = this.collectWordsInString(a);
                    break;
                case "object":
                    c = a.nodeType ? this.collectWordsInContainer(a, b) : this.collectWordsInRange(a)
            }
            return this.sandbox.fire("wordsCollected", {
                wordsCollection: c
            }), c
        },
        collectWordsInString: function(a) {
            var b = this.sandbox.getOption("punctuationRegExp"),
                c = this.sandbox.getOption("lang"),
                d = this.sandbox.getOption("permanentMinWordLength"),
                e = this.sandbox.getOption("minWordLength");
            e = "undefined" == typeof d[c] ? e : d[c], a = this.sandbox.Utils.removePunctuation(a, b), a = this.sandbox.Utils.removeSpecialCharacters(a);
            var f, g = "word_";
            f = this.sandbox.Utils.arrayFilter.call(a.split(/\s/), function(a) {
                return "" !== a && a.length >= e ? !0 : !1
            });
            for (var h = {}, i = 0; i < f.length; i++) h[g + f[i]] = h[g + f[i]] || {
                    word: f[i]
                };
            return h = {
                words: h,
                detectedLanguages: {}
            }, h.detectedLanguages[c] = 1, h
        },
        collectWordsInRange: function(a) {
            var b = this.createStringWithoutScaytElements(a.commonAncestorContainer());
            return this.collectWordsInString(b)
        },
        collectWordsInContainer: function(a, b) {
            var c, d = new SCAYT.WordsFinder.Finder(this.sandbox, b);
            return d.collectBlockInfo(a), d.resultText = d.resultText.replace(/_/g, " "), c = this.collectWordsInString(d.resultText), c.detectedLanguages = d.detectedLanguages, c
        },
        createStringWithoutScaytElements: function(a) {
            for (var b = this.sandbox.UILib, c = "", d = [a], e = d.shift(), f = this.sandbox.getOption("blockElementsRegex"), g = this.sandbox.getOption("misspelled_word_node"), h = this.sandbox.getOption("data_attribute_name"), i = this.sandbox.getOption("ignoreElementsRegex"), j = this.sandbox.getOption("punctuationRegExp"), k = new RegExp("(^|\\s)rangySelectionBoundary(\\s|$)"); e;) {
                switch (e.nodeType) {
                    case 3:
                        c += e.nodeValue;
                        break;
                    case 1:
                        var l = e.nodeName.toLowerCase() == g.toLowerCase() && e.getAttribute(h);
                        if (!l && !k.test(b.attr(e, "className")) && !e.nodeName.match(i)) {
                            for (var m = 0; m < e.childNodes.length; m++) d.splice(m, 0, e.childNodes[m]);
                            e.nodeName.match(f) && (d.length > e.childNodes.length && d.splice(m, 0, document.createTextNode(" ")), c.length > 0 && " " != c[c.length - 1] && d.splice(0, 0, document.createTextNode(" ")))
                        }
                }
                e = d.shift()
            }
            return c = this.sandbox.Utils.removePunctuation(c, j)
        }
    }, a.WordsCollector = b
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b
    };
    b.prototype = {
        init: function() {
            this.sandbox.subscribe("misspelledWordsFound", function(a) {
                this.processMisspelledWords(a.words, a.lang)
            }, this)
        },
        processMisspelledWords: function(a, b) {
            for (var c = this, d = (c.sandbox.getOption("lang"), c.sandbox.getOption("uid")), e = [], f = 0; f < a.length; f++) a[f].existsInInstance(d) && 1 == a[f].getStatus(d) && e.push(a[f]);
            0 !== e.length && c.sandbox.addDeferredFunction("findWordRangesForMarkupForLang_" + b, {
                delay: 100,
                collection: e,
                defferedFunctionArgs: [b],
                partialItemsCount: 1,
                deferredFunction: function(a, b) {
                    var d, e, f = c.sandbox.getOption("focused"),
                        g = c.sandbox.getOption("documentContainer") === document.activeElement;
                    (f || g) && (d = c.sandbox.saveSelection()), e = c.findWordRangesForMarkup(a), c.sandbox.fire("markupWords", {
                        ranges: e,
                        lang: b
                    }), c.sandbox.restoreSelection(d)
                }
            })
        },
        findWordRangesForMarkup: function(a) {
            var c, d = this.sandbox.createRange(),
                e = this.sandbox.getOption("container");
            d.selectNodeContents(e), c = new b.Finder(this.sandbox), c.collectBlockInfo(d.commonAncestorContainer());
            for (var f = [], g = 0; g < a.length; g++) for (c.lastIndex = 0; null !== c.findWord(a[g].word);) f.push({
                range: c.wordRange,
                language: c.wordLanguage
            });
            return f.reverse()
        }
    }, b.Finder = function(a, b) {
        function c(b, c) {
            var d, e = a.getOption("multiLanguageMode"),
                f = a.getOption("languagesMap"),
                g = a.getOption("languageNodeName"),
                h = a.getOption("languageAttributeName"),
                i = c;
            return e && (b.lang && b.nodeName.toLowerCase() === g || (b = a.UILib.parents(b, g + "[" + h + "]")[0]), d = b && b.nodeName.toLowerCase() == g ? b.getAttribute(h) : "", d && (i = f[d] || null)), i
        }
        b = "undefined" == typeof b ? !0 : b;
        var d = "th_TH" === a.getOption("lang");
        this.parts = [], this.newParts = {
            getPos: function(a) {
                for (; !this[a];) a--;
                return this[a]
            }
        }, this.resultText = "", this.detectedLanguages = {}, this.detectedLanguages[a.getOption("lang")] = 1, this.lastIndex = 0, this.wordRange = null, this.reset = function() {
            this.parts = [], this.resultText = "", this.lastIndex = 0, this.wordRange = null, this.detectedLanguages[a.getOption("lang")] = 1
        }, this.collectBlockInfo = function(d) {
            function e(a, b, c) {
                if (a !== b) {
                    var d = {
                        node: c.el,
                        start: i.resultText.length,
                        end: i.resultText.length + b - a,
                        offset: a
                    };
                    i.newParts[d.start] = d, i.newParts[d.end] = d, i.resultText += 0 == c.editable ? c.el.nodeValue.replace(/./g, " ").substring(a, b) : c.el.nodeValue.substring(a, b)
                }
            }
            for (var f = [{
                el: d,
                editable: d.isContentEditable
            }], g = f.shift(), h = a.getOption("lang"), i = this, j = a.getOption("blockElementsRegex"), k = a.getOption("ignoreElementsRegex"), l = a.getOption("misspelled_word_node"), m = a.getOption("data_attribute_name"), n = new RegExp("(^|\\s)rangySelectionBoundary(\\s|$)"), o = 0, p = "", q = [], r = a.getOption("specialCharactersRegex"); g;) {
                switch (g.el.nodeType) {
                    case 3:
                        g.el.nodeValue.length > 0 && (o = g.indexOffset || 0, p = g.el.nodeValue, q = p.substring(o).match(r), q ? (e(o, o + q.index, g), g.indexOffset = o + q.index + q[0].length, f.splice(0, 0, g)) : (e(o, p.length, g), g.emptyCharsCountInPart = 0));
                        break;
                    case 1:
                        if (b && g.el.nodeName.toLowerCase() == l.toLowerCase() && g.el.getAttribute(m)) this.resultText += g.el.getAttribute(m).replace(/./g, "_");
                        else if (!n.test(a.UILib.attr(g.el, "className")) && !k.test(g.el.nodeName)) {
                            var s = g.el.hasAttribute("contenteditable") ? g.el.isContentEditable : g.editable,
                                t = c(g.el, h);
                            t && (this.detectedLanguages[t] = 1);
                            for (var u = 0; u < g.el.childNodes.length; u++) f.splice(u, 0, {
                                el: g.el.childNodes[u],
                                editable: s
                            });
                            g.el.nodeName.match(j) && (f.length > g.el.childNodes.length && f.splice(u, 0, {
                                el: document.createTextNode(" "),
                                editable: !0
                            }), this.resultText.length > 0 && " " != this.resultText[this.resultText.length - 1] && f.splice(0, 0, {
                                el: document.createTextNode(" "),
                                editable: !0
                            }))
                        }
                }
                g = f.shift()
            }
            this.resultText = this.resultText.replace(/[\r\n(\r\n)]/g, " "), this.resultText = a.Utils.removePunctuation(this.resultText, a.getOption("punctuationRegExp"))
        }, this.findWord = function(b) {
            var e = this.resultText.indexOf(b, this.lastIndex);
            if (e > 0) this.lastIndex = e + b.length, d || (e = this.resultText.charAt(e - 1).match(/\s/) ? e : "skipped", e = this.lastIndex == this.resultText.length || this.resultText.charAt(e + b.length).match(/\s/) ? e : "skipped");
            else {
                if (0 !== e) return null;
                this.lastIndex = e + b.length, e = this.lastIndex == this.resultText.length || this.resultText.charAt(e + b.length).match(/\s/) ? e : "skipped"
            }
            if ("skipped" == e) return this.findWord.call(this, b);
            var f = a.createRange(),
                g = this.newParts.getPos(e);
            f.setStart(g.node, e - g.start + g.offset);
            var h = this.newParts.getPos(e + b.length - 1);
            f.setEnd(h.node, e + b.length - h.start + h.offset), f = a.Utils.fixRangeBoundaryPoints(f), this.wordRange = f;
            var i = a.getOption("lang"),
                j = f.commonAncestorContainer();
            return this.wordLanguage = c(j, i), this.wordRange
        }
    }, a.WordsFinder = b
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b
    };
    b.prototype = {
        init: function() {
            this.sandbox.subscribe("replaceWord", function(a) {
                this.replaceWordInSelection(a.word, a.scaytNode)
            }, this), this.sandbox.subscribe("ignoreWord", function(a) {
                this.ignoreWordInSelection(a.scaytNode)
            }, this), this.sandbox.subscribe("ignoreAllWords", function(a) {
                this.ignoreWordInDocument(a.scaytNode)
            }, this)
        },
        replaceWordInSelection: function(a, b) {
            var c;
            c = b ? b : this.sandbox.getScaytNodeFromSelection(), c && this.replaceWordByNode(c, a)
        },
        ignoreWordInSelection: function(a) {
            var b;
            b = a ? a : this.sandbox.getScaytNodeFromSelection(), b && this.ignoreWords([b])
        },
        ignoreWordInDocument: function(a) {
            var b, c, d, e = this.sandbox.getOption("container"),
                f = this.sandbox.getOption("misspelled_word_node"),
                g = this.sandbox.getOption("data_attribute_name"),
                h = this.sandbox.getOption("data_lang_attribute"),
                i = this.sandbox.UILib,
                j = [];
            b = a ? a : this.sandbox.getScaytNodeFromSelection(), b && (d = b.getAttribute(h), c = this.sandbox.DOM.query(e, f + "[" + g + '="' + b.getAttribute(g) + '"]'), c = i.filter(c, "[" + h + '="' + d + '"]'), j.push.apply(j, c), this.ignoreWords(j))
        },
        ignoreWords: function(b) {
            for (var c, d, e, f, g = this.sandbox.saveSelection(), h = this.sandbox.createRange(), i = a.DictionaryManager.Dictionary, j = this.sandbox.getOption("data_attribute_name"), k = this.sandbox.getOption("data_lang_attribute"), l = this.sandbox.getOption("uid"); b.length > 0;) c = b.shift(), d = c.getAttribute(j), e = c.getAttribute(k), i.getWord(d, e) && i.getWord(d, e).setStatus(a.DictionaryManager.wordStatus.userIgnore, l), h.selectNode(c), f = h.createContextualFragment(c.innerHTML), h.deleteContents(), this.sandbox.fire("removedMarkupInContainer", {
                ancestorContainer: h.commonAncestorContainer()
            }), h.insertNode(f);
            this.sandbox.restoreSelection(g)
        },
        replaceWordByNode: function(a, b) {
            a.innerHTML = b;
            var c = this.sandbox.createRange();
            c.selectNodeContents(a), c.collapse(!1);
            var d = this.sandbox.getSelection();
            d.removeAllRanges(), d.addRange(c);
            var e = this.sandbox.saveSelection();
            c = this.sandbox.createRange(), c.selectNode(a);
            var f = c.createContextualFragment(a.innerHTML);
            c.deleteContents(), c.insertNode(f), this.sandbox.fire("removedMarkupInContainer", {
                ancestorContainer: c.commonAncestorContainer()
            }), this.sandbox.restoreSelection(e)
        }
    }, a.WordsProcessor = b
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        var c = (b.getOption("basePath") + "css/close.png", b.getOption("basePath") + "css/webspellchecker-logo-small.png"),
            d = b.getOption("bannerTemplate"),
            e = b.getOption("bannerType");
        this.name = a, this.sandbox = b, this.closeBannerTimeout = void 0, this.contextMenuContainer = null, this.template = d || '<div id="scayt_banner" style="padding: 2px 18px 14px; border: 1px solid #c7c7c7; box-shadow: 0 0 5px rgba(0,0,0,.1); position: absolute; font-size: 12px; line-height: 1.33; font-family: Arial,Verdana,sans-serif; z-index: 9998; width: 140px; min-height: 60px; background-color: rgb(255, 255, 255); white-space: normal; left: 102%; top: 0; background-position: initial initial; background-repeat: initial initial; color: #3f3f3f; box-sizing: content-box;"><div style="overflow: hidden;"><div class="img-banner"><img src="' + c + '"><span style="display: inline-block; position: relative; font-size: 11px; color: #134aad; font-weight: 700; vertical-align: top; margin-top: 15px;">WebSpellChecker</span></div></div><ul style="list-style-type: disc; margin-top: 5px; margin-left: 25px;"><li style="color: #3f3f3f; line-height: 1.8;"><span style="color: #1E8914; vertical-align: middle;">Accelerated check</span></li><li style="color: #3f3f3f; line-height: 1.8;">More languages</li><li style="color: #3f3f3f; line-height: 1.8;">Technical support</li><li style="color: #3f3f3f; line-height: 1.8;">Extra features</li><li style="color: #3f3f3f; line-height: 1.8;">No banner</li></ul><div style="text-align: center;"><a target="_blank" href="http://www.webspellchecker.net/pricing.html" style="display: inline-block; text-align: center; padding: 3px 16px; border-radius: 6px; background: #1E8914; color: #fff; font-size: 11px; outline: 0; border: 0; cursor: pointer; box-sizing: border-box; line-height: 1.8; margin: 10px auto 0;">Upgrade Now</a></div></div>', this.bannerId = e ? "banner_tpl_" + e : "banner_tpl_default"
    };
    b.prototype = {
        init: function() {
            this.sandbox;
            this.sandbox.Template.create(this.bannerId, this.template), this.sandbox.subscribe("showBanner", function(a) {
                this.showBannerHandler(a.contextMenuContainerSelector)
            }, this), this.sandbox.subscribe("hideBanner", function() {
                this.hideBanner()
            }, this)
        },
        showBannerHandler: function(a) {
            var b = this,
                c = this.sandbox.UILib;
            b.sandbox.getOption("isPaidVersion") === !1 && b.sandbox.addDeferredFunction("showBanner", {
                single: !0,
                delay: 100,
                deferredFunction: function() {
                    var d = c.find(a)[0];
                    b.contextMenuContainer = d, d && (c.css(d, {
                        overflow: "visible"
                    }), b.showBanner(d))
                }
            })
        },
        actionLinks: function(a) {
            var b = this,
                c = a.target || a.srcElement;
            c.href && "closeBanner" !== c.id && (window.open(c.href, "_blank"), b.contextMenuContainer && b.sandbox.fire({
                eventType: "focus",
                element: b.contextMenuContainer
            }))
        },
        showBanner: function(a) {
            function b(a) {
                var e = a;
                f(e), c.sandbox.unsubscribe({
                    eventType: "mousedown",
                    element: d.find("#scayt_banner")[0],
                    handler: b
                })
            }
            var c = this,
                d = this.sandbox.UILib,
                e = c.sandbox.Template.render(c.bannerId, {}),
                f = d.proxy(c.actionLinks, c);
            d.append(a, e), c.sandbox.subscribe({
                eventType: "mousedown",
                element: d.find("#scayt_banner")[0],
                handler: b
            })
        },
        hideBanner: function() {
            var a = this.sandbox.UILib,
                b = a.find("#scayt_banner")[0];
            b && (a.css(a.parent(b), {
                overflow: ""
            }), a.remove(b))
        }
    }, a.Banner = b
}(SCAYT), function(a) {
    "use strict";
    var b;
    if (!a.AccessLimiter) {
        var c = function(a, c) {
            this.name = a, this.delay = c.getOption("spellCheckDelay"), this.wordsLimit = c.getOption("wordsLimit"), this.setTimeoutId = null, this.sandbox = c, b = this.sandbox.Utils
        };
        c.prototype = {
            init: function() {
                this.sandbox;
                this.sandbox.subscribe("subscriptionTypeChecked", function(a) {
                    this.subscriptionCheckedHandler(a)
                })
            },
            subscriptionCheckedHandler: function(a) {
                "free" === a.subscriptionType && (this.limitController = c.limitController = c.limitController || new d({
                        wordsLimit: this.wordsLimit
                    }), this.sandbox.subscribe("getWordsLimit", function(a) {
                    this.getWordsLimitHandler(a)
                }), this.sandbox.subscribe("sentWordsCount", function(a) {
                    this.sentWordsCountHandler(a.count)
                }), this.sandbox.subscribe("spellCheckEnded", function() {
                    this.spellCheckEndedHandler()
                }))
            },
            getWordsLimitHandler: function(a) {
                a.setReturnedData({
                    data: this.limitController.getWordsLimit()
                })
            },
            sentWordsCountHandler: function(a) {
                a = this.limitController.getWordsLimit() - a, this.limitController.updateWordsLimit(0 > a ? 0 : a)
            },
            spellCheckEndedHandler: function() {
                var a = this;
                this.limitController.isFrozen() && null === this.setTimeoutId && (this.sandbox.fireInAllApps("freeze", {
                    status: !0
                }), this.setTimeoutId = setTimeout(function() {
                    a.limitController.clear(), a.setTimeoutId = null, a.sandbox.fireInAllApps("freeze", {
                        status: !1
                    }), a.sandbox.fireInAllApps("startSpellCheck", {})
                }, this.delay))
            }
        };
        var d = function(a) {
            var b = !1,
                c = a.wordsLimit;
            return {
                clear: function() {
                    c = a.wordsLimit, b = !1
                },
                isFrozen: function() {
                    return b
                },
                getWordsLimit: function() {
                    return c
                },
                updateWordsLimit: function(a) {
                    c = a, 0 === a && (b = !0)
                }
            }
        };
        a.AccessLimiter = c
    }
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b
    };
    b.prototype = {
        init: function() {
            var a = this;
            this.sandbox.subscribe({
                eventType: "keydown",
                element: this.getContainer(),
                handler: this.handleKeydown
            }), a.sandbox.subscribe("appStarted", function() {
                a.sandbox.subscribe({
                    eventType: "compositionstart",
                    element: this.getContainer(),
                    handler: function() {
                        a.sandbox.setPaused(!0)
                    }
                }), a.sandbox.subscribe({
                    eventType: "compositionend",
                    element: this.getContainer(),
                    handler: function() {
                        a.sandbox.setPaused(!1), a.sandbox.addDeferredFunction("collectWordsAfterWorkIME", {
                            single: !0,
                            delay: 0,
                            deferredFunction: function() {
                                var b, c = a.sandbox.getSelection(),
                                    d = a.sandbox.getOption("multiLanguageMode");
                                if (c.rangeCount() > 0) {
                                    var e = c.getRangeAt(0);
                                    b = d ? e.commonAncestorContainer() : e, a.sandbox.fire("collectWords", {
                                        source: b
                                    })
                                }
                            }
                        })
                    }
                })
            }, a)
        },
        handleKeydown: function(a) {
            var b = this;
            (229 === a.keyCode || 0 === a.keyCode) && b.sandbox.fire("removeMarkupInSelectionNode")
        },
        getContainer: function() {
            var a = this;
            return a.sandbox.getOption("container")
        }
    }, a.IME = b
}(SCAYT), SCAYT.UI = SCAYT.UI || {}, function(a, b) {
    "use strict";
    var c = b.UILib,
        d = b.Utils;
    a = a || {};
    var e = d.extend(null, {
        appendTo: function(a) {
            c.appendTo(this.getDOMElement(), a)
        },
        insertBefore: function(a) {
            c.insertBefore(this.getDOMElement(), a)
        },
        insertAfter: function(a) {
            c.insertAfter(this.getDOMElement(), a)
        },
        getParentDialog: function() {
            return this.dialog
        },
        getDOMElement: function() {
            return this.element
        },
        css: function(a) {
            c.css(this.getDOMElement(), a)
        },
        hideElement: function() {
            this.getDOMElement().style.display = "none"
        },
        showElement: function() {
            this.getDOMElement().style.display = ""
        }
    });
    a.Component = e
}(SCAYT.UI, SCAYT.prototype), SCAYT.UI = SCAYT.UI || {}, function(a) {
    "use strict";
    var b = function(a, b, c) {
        this.container = a || document, this.keysMap = b, this.sandbox = c, this.isActive = !1, this.activate = function() {
            this.isActive || (this.isActive = !0, this.sandbox.subscribe({
                eventType: "keydown",
                element: this.container,
                handler: e
            }))
        }, this.deActivate = function() {
            this.isActive = !1, this.sandbox.unsubscribe({
                eventType: "keydown",
                element: this.container,
                handler: e
            })
        }, this.destroy = function() {
            this.deActivate()
        };
        var d = this,
            e = function(a) {
                var b, c = a.keyCode;
                for (var e in d.keysMap) e == c && "function" == typeof d.keysMap[e] && (b = d.keysMap[e](a), b && a.preventDefault())
            }
    };
    a.KeyboardNavigation = b
}(SCAYT.UI, SCAYT.prototype), SCAYT.UI = SCAYT.UI || {}, function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib,
        e = c.extend(a.Component, function(f, g) {
            function h() {
                z.element = E = i(), F = d.find(".sc-dialog__header-drag", E), G = d.find(".sc-dialog__header .sc-dialog__header-in", E), J = d.find(".sc-dialog__header .sc-dialog__header-title", E), K = d.find(".sc-dialog__content", E), H = new a.Button({
                    id: "close",
                    text: "&#65279;",
                    title: f.getLocal("btn_close", f),
                    extraClass: "sc-button__icon sc-button__icon_close",
                    onClick: s
                }, z), I = new a.Button({
                    id: "info",
                    text: "&#65279;",
                    title: f.getLocal("btn_info", f),
                    href: "http://scayt.com/user_manual/scayt_for_editable_controls_user_manual.pdf",
                    target: "_blank",
                    extraClass: "sc-button__icon sc-button__icon_info"
                }, z), H.appendTo(G), I.appendTo(G), "function" == typeof z.onLoad && z.subscribe("onLoad", z.onLoad, z), "function" == typeof z.onShow && z.subscribe("onShow", z.onShow, z), "function" == typeof z.onHide && z.subscribe("onHide", z.onHide, z), "function" == typeof z.onClose && z.subscribe("onClose", z.onClose, z), z.subscribe("afterTabShow", z.refreshFocusableElements, z), z.subscribe("userDictionaryAction", z.refreshFocusableElements, z), z.addTabs(z.tabDefinitions), j(), t(), f.fire("dialogDefinition", {
                    name: g,
                    definition: A,
                    dialog: z
                }), z.fire("onLoad", {
                    sender: z
                })
            }
            function i() {
                var a = "";
                return D.create(R.name, R.text), a = D.render(R.name, {
                    titleHtml: z.title,
                    label: z.label,
                    extraClass: z.extraClass
                }), d.create(a)[0]
            }
            function j() {
                "number" == typeof z.minWidth && d.css(E, {
                    width: z.minWidth
                }), "number" == typeof z.minHeight && d.css(E, {
                    height: z.minHeight
                })
            }
            function k() {
                var a, b = d.find("." + P)[0],
                    e = {
                        display: "block"
                    };
                b = b || d.create('<div class="' + P + '">')[0], c.browser.ie && c.browser.version < 9 ? (a = Math.round(100 * Q), e.filter = a >= 100 ? "" : "progid:DXImageTransform.Microsoft.Alpha(opacity=" + a + ")") : e.opacity = Q, d.css(b, e), d.appendTo(b, "body")
            }
            function l() {
                var a = d.find("." + P)[0];
                a && d.css(a, {
                    display: "none"
                })
            }
            function m(a) {
                a ? (f.subscribe({
                    eventType: "resize",
                    element: window,
                    handler: n
                }), o()) : (clearTimeout(y), f.unsubscribe({
                    eventType: "resize",
                    element: window,
                    handler: n
                }))
            }
            function n(a) {
                clearTimeout(y), y = setTimeout(o, S)
            }
            function o() {
                var a = 0,
                    b = 0,
                    c = p(),
                    d = q(),
                    e = B.getScrollLeft(),
                    f = B.getScrollTop(),
                    g = "fixed";
                g = d.height > c.height ? "fixed" : "absolute", a = parseInt((d.width - c.width) / 2, 10), b = parseInt((d.height - c.height) / 2, 10), "absolute" == g && (a = e + a, b = f + b, a = 0 > a ? 0 : a, b = 0 > b ? 0 : b), z.setPosition(a, b, g)
            }
            function p() {
                var a = {};
                return a.width = d.outerWidth(E, !0), a.height = d.outerHeight(E, !0), a
            }
            function q() {
                var a = {};
                return a.width = B.getWindowInnerWidth(), a.height = B.getWindowInnerHeight(), a
            }
            function r(a, b) {
                for (var c in b) {
                    if (c === a) return b[c];
                    if (b[c].getChildren) {
                        var d = r(a, b[c].getChildren());
                        if (d) return d
                    }
                }
                return null
            }
            function s() {
                z.hide(), z.fire("onClose", {
                    sender: z
                }), z.fire("restoreSelection")
            }
            function t() {
                function a(a) {
                    e = a.clientX - parseInt(E.style.left), g = a.clientY - parseInt(E.style.top), d.addClass("html", "sc-unselectable"), b(a), f.subscribe({
                        eventType: "mousemove",
                        element: document,
                        handler: b
                    }), f.subscribe({
                        eventType: "mouseup",
                        element: document,
                        handler: c
                    })
                }
                function b(a) {
                    E.style.left = a.clientX - e + "px", E.style.top = a.clientY - g + "px"
                }
                function c() {
                    d.removeClass("html", "sc-unselectable"), f.unsubscribe({
                        eventType: "mousemove",
                        element: document,
                        handler: b
                    }), f.unsubscribe({
                        eventType: "mouseup",
                        element: document,
                        handler: c
                    })
                }
                var e, g;
                f.subscribe({
                    eventType: "mousedown",
                    element: F[0],
                    handler: a
                })
            }
            function u() {
                for (var a = document.activeElement, b = 0; b < z.focusableElements.length; b++) a === z.focusableElements[b] && (z.focusIndex = b);
                return z.focusIndex++, z.focusIndex >= z.focusableElements.length && (z.focusIndex = 0), z.setFocus(z.focusIndex), !0
            }
            function v() {
                var a, b = document.activeElement,
                    c = z.getActiveTabIndex(),
                    e = z.getTabsLength(),
                    f = c - 1;
                return d.hasClass(b, "sc-tabset__link") ? (0 > f && (f = e - 1), z.lockFocusIndexChange = !0, a = z.getTab(f), a.onClick(), !0) : !1
            }
            function w() {
                var a, b = document.activeElement,
                    c = z.getActiveTabIndex(),
                    e = z.getTabsLength(),
                    f = c + 1;
                return d.hasClass(b, "sc-tabset__link") ? (f >= e && (f = 0), z.lockFocusIndexChange = !0, a = z.getTab(f), a.onClick(), !0) : !1
            }
            function x() {
                return H.onClick(), !0
            }
            var y, z = this,
                A = e._.dialogDefinitions[g],
                B = (f.getOption("container"), SCAYT.UIMetrics),
                C = SCAYT.UI.KeyboardNavigation,
                D = b.Template,
                E = null,
                F = null,
                G = null,
                H = null,
                I = null,
                J = null,
                K = null,
                L = [],
                M = {},
                N = null,
                O = "one-tab",
                P = "sc-modal-cover",
                Q = .6,
                R = {
                    name: "uiDialogTpl",
                    text: '<div class="sc-dialog <%=extraClass%>"><div class="sc-dialog__header"><div class="sc-dialog__header-in"></div><div class="sc-dialog__header-title"><%=titleHtml%></div><div class="sc-dialog__header-drag" title="<%=label%>"></div></div><div class="sc-dialog__content"></div></div>'
                },
                S = 100;
            A = A(f), this.dialogName = g, this.title = A.title || "", this.label = "SCAYT" === this.title ? "SpellCheckAsYouType" : this.title, this.buttonDefinitions = L.concat(A.buttons || []), this.tabDefinitions = A.tabs || {}, this.extraClass = A.extraClass || "", this.minWidth = A.minWidth, this.minHeight = A.minHeight, this.onLoad = A.onLoad, this.onShow = A.onShow, this.onHide = A.onHide, this.onClose = A.onClose, R = A.elementTemplate ? A.elementTemplate : R, this.focusableElements = [], this.focusIndex = 0, this.lockFocusIndexChange = !1, this.keyboardNavigation = new C(document, {
                9: u,
                37: v,
                39: w,
                27: x
            }, f), this.show = function() {
                k(), d.appendTo(E, "body"), m(!0), this.fire("saveSelection"), this.fire("onShow", {
                    sender: z
                }), c.browser.ie && c.browser.version <= 8 || this.keyboardNavigation.activate()
            }, this.hide = function() {
                m(!1), d.remove(E), l(), this.fire("onHide", {
                    sender: z
                }), c.browser.ie && c.browser.version <= 8 || this.keyboardNavigation.deActivate()
            }, this.setTitle = function(a) {
                d.html(J, a)
            }, this.addTab = function(b) {
                N = N || new a.TabbedNavigation({
                        appendTo: K
                    }, this), N.addTab(b), this.updateStyles()
            }, this.addTabs = function(b) {
                b && b.length > 0 && (N = N || new a.TabbedNavigation({
                        appendTo: K
                    }, this), N.addTabs(b), this.updateStyles())
            }, this.getTabsLength = function() {
                return N ? N.getTabsLength() : 0
            }, this.getActiveTabIndex = function() {
                return N ? N.getActiveTabIndex() : 0
            }, this.getTab = function(a) {
                return N ? N.getTab(a) : null
            }, this.setActiveTab = function(a) {
                N && N.setActiveTab(a)
            }, this.removeTab = function(a) {
                var b = !1;
                return N ? (b = N.removeTab(a), this.updateStyles(), b) : void 0
            }, this.updateStyles = function() {
                var a = N.getTabsLength();
                d[2 > a ? "addClass" : "removeClass"](E, O)
            }, this.setPosition = function(a, b, c) {
                c = c || "absolute", d.css(E, {
                    position: c
                }), d.setPosition(E, a, b)
            }, this.find = function(a) {
                return d.find(a, E)
            }, this.getFocusableElements = function() {
                for (var a = z.getTab(z.getActiveTabIndex()), b = d.find(".sc-focusable", a.element), c = d.find(".sc-focusable", G), e = d.find(".sc-tabset__tab_active a", E), f = b.concat(c).concat(e), g = [], h = 0; h < f.length; h++) {
                    for (var i = f[h], j = !1; i !== E;) {
                        if ("none" === d.css(i, "display")) {
                            j = !0;
                            break
                        }
                        i = i.parentNode
                    }
                    j || g.push(f[h])
                }
                return g
            }, this.refreshFocusableElements = function() {
                var a = this;
                c.browser.ie && c.browser.version <= 8 || setTimeout(function() {
                    a.focusableElements = a.getFocusableElements(), a.focusIndex = a.lockFocusIndexChange ? a.focusableElements.length - 1 : 0, a.setFocus(a.focusIndex), a.lockFocusIndexChange = !1
                }, 0)
            }, this.setFocus = function(a) {
                this.focusableElements[a].focus()
            }, this.getUIElement = function(a, b) {
                var c = null,
                    d = null,
                    e = null;
                return N && (d = N.getTab(a), e = d.getChildren(), c = r(b, e)), c
            }, this.getButton = function(a) {
                return M[a]
            }, this.fire = function(a, b) {
                return f.fire(a, b)
            }, this.subscribe = function(a, b, c, d) {
                return f.subscribe(a, b, c, d)
            }, this.unsubscribe = function(a, b) {
                return f.unsubscribe(a, b)
            }, this.destroy = function() {
                H.destroy(), H = null, I.destroy(), I = null;
                for (var a in M) M[a].destroy(), delete M[a];
                N && (N.destroy(), N = null), d.remove(E), l(), E = null, F = null, G = null, J = null, K = null, this.unsubscribe("onLoad", this), this.unsubscribe("onShow", this), this.unsubscribe("onHide", this), this.unsubscribe("onClose", this), this.unsubscribe("afterTabShow", this), this.unsubscribe("userDictionaryAction", this);
                for (var b in this) this.hasOwnProperty(b) && delete this[b]
            }, h()
        });
    e.add = function(a, b) {
        e._.dialogDefinitions[a] || (e._.dialogDefinitions[a] = b)
    }, e.getNextId = function() {
        var a = 0;
        return function(b) {
            return (b || "") + ++a
        }
    }(), e._ = {
        dialogDefinitions: {}
    }, a.Dialog = e, a._ = a._ || {}, a._.uiElements = a._.uiElements || {}, a.registerUIElement = function(a, b) {
        this._.uiElements[a] = b
    }, a.createUIElement = function(a, b, c) {
        var d = this._.uiElements[a],
            e = null;
        return "function" == typeof d && (e = new d(b, c)), e
    }
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict"; {
        var c = b.Utils;
        b.UILib
    }
    a = a || {};
    var d = c.extend(a.Component, function(c, d) {
        function e() {
            k.appendTo && (f(), k.addTabs(k.tabDefinitions), k.setActiveTab(c.activeIndex))
        }
        function f() {
            var a = "",
                b = null;
            n.create(s.name, s.text), a = n.render(s.name, {
                extraClass: k.extraClass
            }), b = l.appendTo(a, k.appendTo), o = l.filter(b, ".sc-tabset")[0], o || (o = l.find(".sc-tabset", b)[0]), k.element = p = l.filter(b, ".sc-tabview-panel")[0], p || (p = l.find(".sc-tabview-panel", b)[0])
        }
        function g(a) {
            return q[a]
        }
        function h(a) {
            return q[m.getKeys(q)[a]]
        }
        function i(a) {
            var b = -1;
            for (var c in q) if (b++, c == a.id) break;
            return b
        }
        function j(a) {
            var b, c = k.getTab(a),
                d = null,
                e = 0;
            return c && (b = m.getKeys(q), b.length > 1 && (e = b.indexOf(c.id) + 1, "undefined" == typeof b[e] && (e = 0), d = k.getTab(e))), d
        }
        var k = this,
            l = b.UILib,
            m = b.Utils,
            n = b.Template,
            o = null,
            p = null,
            q = {},
            r = 0,
            s = {
                name: "uiTabbedNavTpl",
                text: '<ul class="sc-tabset <%=extraClass%>"></ul><div class="sc-tabview-panel <%=extraClass%>"></div>'
            };
        this.appendTo = c.appendTo, this.tabDefinitions = c.tabs || [], r = c.activeIndex || r, this.extraClass = c.extraClass || "", this.dialog = d, this.addTab = function(b) {
            var c, e;
            e = new a.Tab({
                id: b ? b.id : "",
                title: b ? b.title : "",
                style: b.style || "",
                extraClass: b.extraClass || "",
                elements: b.elements || [],
                tabset: o,
                tabsHolder: p,
                onLoad: b.onLoad,
                onShow: b.onShow,
                onHide: b.onHide,
                onClick: function() {
                    k.setActiveTab(e.id), b.onClick && b.onClick.call(this)
                }
            }, d), q[e.id] && k.removeTab(e.id), q[e.id] = e, e.hide(), c = k.getTab(r), c && c.isActive() || k.setActiveTab(0)
        }, this.addTabs = function(a) {
            for (var b, c = 0; b = a[c], c < a.length; c++) this.addTab(b)
        }, this.removeTab = function(a) {
            var b = !1,
                c = null,
                d = k.getTab(a);
            return d && (d.isActive() && (c = j(a), c && k.setActiveTab(c.id)), delete q[d.id], d.destroy(), b = !0), b
        }, this.getActiveTabIndex = function() {
            return r
        }, this.setActiveTab = function(a) {
            var b = k.getTab(a);
            if (b) {
                r = i(b);
                for (var c in q) q[c].hide();
                b.show(), this.dialog.fire("afterTabShow", {
                    tab: b
                })
            }
        }, this.getTab = function(a) {
            var b = null;
            switch (typeof a) {
                case "string":
                    b = g(a);
                    break;
                case "number":
                    b = h(a)
            }
            return b
        }, this.getTabsLength = function() {
            return m.getKeys(q).length
        }, this.destroy = function() {
            for (var a in q) q[a].destroy();
            q = {}, l.remove(o), l.remove(p);
            for (var b in this) this.hasOwnProperty(b) && delete this[b]
        }, e()
    });
    a.TabbedNavigation = d
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(c, e) {
        function f() {
            e.subscribe("onLoad", function(a) {
                a.sender.dialogName === e.dialogName && (i(), "function" == typeof k.onLoad && k.onLoad.call(k, a))
            }, k), "function" == typeof k.onShow && e.subscribe("onShow", k.onShow, k), "function" == typeof k.onHide && e.subscribe("onHide", k.onHide, k), g()
        }
        function g() {
            var b = "",
                c = "";
            l.create(p.name, p.text), b = l.render(p.name, {
                extraClass: k.extraClass,
                label: k.title,
                href: k.id
            }), m = d.create(b)[0], d.appendTo(m, k.tabset), m = d.filter(m, ".sc-tabset__tab")[0], m || (m = d.find(".sc-tabset__tab", m)[0]), l.create(q.name, q.text), c = l.render(q.name, {
                extraClass: k.extraClass
            }), k.element = n = d.create(c)[0], o = a.createUIElement("vbox", {
                type: "vbox",
                extraClass: "sc-tabset__tab-content",
                style: k.style,
                children: k.elementsDefinitions
            }, e), o.appendTo(n), d.appendTo(n, k.tabsHolder)
        }
        function h(a) {
            a.preventDefault(), "function" == typeof k.onClick && k.onClick.call(k, {
                event: a
            })
        }
        function i() {
            e.subscribe({
                eventType: "click",
                element: d.find("a", m)[0],
                handler: h
            })
        }
        function j() {
            e.unsubscribe({
                eventType: "click",
                element: d.find("a", m)[0],
                handler: h
            })
        }
        var k = this,
            l = b.Template,
            m = null,
            n = null,
            o = null,
            p = {
                name: "uiTabSwitcherHolderTpl",
                text: '<li class="sc-tabset__tab <%=extraClass%>"><a class="sc-tabset__link" href="#tab-<%=href%>" title="<%=label%>"><span class="sc-tabset__tab-text"><%=label%></span></a></li>'
            },
            q = {
                name: "uiTabTpl",
                text: '<div class="sc-tabset__tab-panel <%=extraClass%>"></div>'
            };
        this.id = c.id || a.Dialog.getNextId("sc-tab_"), this.title = c.title || this.id, this.style = c.style || "width: 100%;", this.extraClass = c.extraClass || "", this.elementsDefinitions = c.elements || [], this.activeClass = "sc-tabset__tab_active", this.tabset = c.tabset, this.tabsHolder = c.tabsHolder, this.onLoad = c.onLoad, this.onShow = c.onShow, this.onHide = c.onHide, this.onClick = c.onClick, this.dialog = e, this.show = function() {
            d.addClass(m, k.activeClass), d.css(n, {
                display: "block"
            })
        }, this.hide = function() {
            d.removeClass(m, k.activeClass), d.css(n, {
                display: "none"
            })
        }, this.isActive = function() {
            return d.hasClass(m, k.activeClass)
        }, this.getChildren = function() {
            return o.getChildren()
        }, this.destroy = function() {
            j(), e.unsubscribe("onLoad", this), e.unsubscribe("onShow", this), e.unsubscribe("onHide", this), o.destroy(), d.remove(m), d.remove(d.find("a", m)[0]), d.remove(n);
            for (var a in this) this.hasOwnProperty(a) && delete this[a]
        }, f()
    });
    a.Tab = e
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(c, e) {
        function f() {
            e.subscribe("onLoad", function(a) {
                a.sender.dialogName === e.dialogName && (h(), "function" == typeof o.onLoad && o.onLoad.call(o, a))
            }, o), "function" == typeof o.onShow && e.subscribe("onShow", o.onShow, o), "function" == typeof o.onHide && e.subscribe("onHide", o.onHide, o), o.storable && e.subscribe("onClose", function(a) {
                a.sender.dialogName === e.dialogName && o.commit()
            }, o), o.element = q = g()
        }
        function g() {
            var a = "",
                b = null;
            return p.create(t.name, t.text), a = p.render(t.name, {
                radioId: o.id,
                name: o.name,
                value: o.value,
                labelText: o.label,
                checked: c.checked ? "checked" : "",
                disabled: c.disabled ? "disabled" : "",
                style: o.style,
                extraClass: c.disabled ? s + " " + o.extraClass : o.extraClass
            }), b = d.create(a)[0], r = d.find("input", b)[0], b
        }
        function h() {
            e.subscribe({
                eventType: "focus",
                element: r,
                handler: j
            }), e.subscribe({
                eventType: "blur",
                element: r,
                handler: k
            }), e.subscribe({
                eventType: "click",
                element: r,
                handler: l
            }), e.subscribe({
                eventType: "change",
                element: r,
                handler: m
            }), e.subscribe({
                eventType: "keydown",
                element: r,
                handler: n
            })
        }
        function i() {
            e.unsubscribe({
                eventType: "focus",
                element: r,
                handler: j
            }), e.unsubscribe({
                eventType: "blur",
                element: r,
                handler: k
            }), e.unsubscribe({
                eventType: "click",
                element: r,
                handler: l
            }), e.unsubscribe({
                eventType: "change",
                element: r,
                handler: m
            }), e.unsubscribe({
                eventType: "keydown",
                element: r,
                handler: n
            })
        }
        function j(a) {
            var b = a;
            o.isDisabled() && b.preventDefault(), "function" != typeof o.onFocus || o.isDisabled() || o.onFocus.call(o, {
                event: a
            })
        }
        function k(a) {
            var b = a;
            o.isDisabled() && b.preventDefault(), "function" != typeof o.onBlur || o.isDisabled() || o.onBlur.call(o, {
                event: a
            })
        }
        function l(a) {
            var b = a;
            o.isDisabled() && b.preventDefault(), "function" != typeof o.onClick || o.isDisabled() || o.onClick.call(o, {
                event: a
            })
        }
        function m(a) {
            var b = a;
            o.isDisabled() && b.preventDefault(), "function" != typeof o.onChange || o.isDisabled() || o.onChange.call(o, {
                event: a
            })
        }
        function n(a) {
            var b = a;
            o.isDisabled() && b.preventDefault(), "function" != typeof o.onKeydown || o.isDisabled() || o.onKeydown.call(o, {
                event: a
            })
        }
        var o = this,
            p = b.Template,
            q = null,
            r = null,
            s = "sc-radio_disabled",
            t = {
                name: "uiRadioTpl",
                text: '<span class="sc-radio-wrapper <%=extraClass%>" style="<%=style%>"><input id="<%=radioId%>" name="<%=name%>" class="sc-input-radio sc-focusable" value="<%=value%>" type="radio" <%=checked%> <%=disabled%> /><label for="<%=radioId%>"><%=labelText%></label></span>'
            };
        this.id = c.id || a.Dialog.getNextId("sc-radio_"), this.name = c.name || "", this.type = c.type, this.value = c.value || "", this.storable = !! c.storable, this.storedValue = !! c.checked, this.label = c.label || "", this.style = c.style || "", this.extraClass = c.extraClass || "", this.onLoad = c.onLoad, this.onShow = c.onShow, this.onHide = c.onHide, this.onFocus = c.onFocus, this.onBlur = c.onBlur, this.onClick = c.onClick, this.onChange = c.onChange, this.onKeydown = c.onKeydown, this.dialog = e, this.getInputElement = function() {
            return r
        }, this.check = function() {
            this.isDisabled() || (r.checked = !0)
        }, this.uncheck = function() {
            this.isDisabled() || (r.checked = !1)
        }, this.isChecked = function() {
            return r.checked
        }, this.setValue = function(a) {
            this.isDisabled() || (r.value = a)
        }, this.getValue = function() {
            return r.value
        }, this.enable = function() {
            d.removeClass(q, s), r.disabled = !1
        }, this.disable = function() {
            d.addClass(q, s), r.disabled = !0
        }, this.isDisabled = function() {
            return d.hasClass(q, s) && r.disabled
        }, this.commit = function() {
            this.storedValue = this.isChecked()
        }, this.reset = function() {
            this[this.storedValue ? "check" : "uncheck"](), this.commit()
        }, this.isChanged = function() {
            return this.storedValue !== this.isChecked()
        }, this.destroy = function() {
            e.unsubscribe("onLoad", this), e.unsubscribe("onShow", this), e.unsubscribe("onHide", this), e.unsubscribe("onClose", this), i(), d.remove(q);
            for (var a in this) this.hasOwnProperty(a) && delete this[a]
        }, f()
    });
    a.RadioButton = e, a.registerUIElement("radio", e)
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(c, e) {
        function f() {
            e.subscribe("onLoad", function(a) {
                a.sender.dialogName === e.dialogName && (h(), "function" == typeof o.onLoad && o.onLoad.call(o, a))
            }, this), "function" == typeof o.onShow && e.subscribe("onShow", o.onShow, o), "function" == typeof o.onHide && e.subscribe("onHide", o.onHide, o), o.storable && e.subscribe("onClose", function(a) {
                a.sender.dialogName === e.dialogName && o.commit()
            }, o), o.element = q = g()
        }
        function g() {
            var a = "",
                b = null;
            return p.create(t.name, t.text), a = p.render(t.name, {
                checkboxId: o.id,
                name: o.name,
                value: o.value,
                labelText: o.label,
                checked: c.checked ? "checked" : "",
                disabled: c.disabled ? "disabled" : "",
                style: o.style,
                extraClass: c.disabled ? s + " " + o.extraClass : o.extraClass
            }), b = d.create(a)[0], r = d.find("input", b)[0], b
        }
        function h() {
            e.subscribe({
                eventType: "focus",
                element: r,
                handler: j
            }), e.subscribe({
                eventType: "blur",
                element: r,
                handler: k
            }), e.subscribe({
                eventType: "click",
                element: r,
                handler: l
            }), e.subscribe({
                eventType: "keydown",
                element: r,
                handler: n
            }), e.subscribe({
                eventType: "change",
                element: r,
                handler: m
            })
        }
        function i() {
            e.unsubscribe({
                eventType: "focus",
                element: r,
                handler: j
            }), e.unsubscribe({
                eventType: "blur",
                element: r,
                handler: k
            }), e.unsubscribe({
                eventType: "click",
                element: r,
                handler: l
            }), e.unsubscribe({
                eventType: "keydown",
                element: r,
                handler: n
            }), e.unsubscribe({
                eventType: "change",
                element: r,
                handler: m
            })
        }
        function j(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onFocus || o.isDisabled() || o.onFocus.call(o, {
                event: a
            })
        }
        function k(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onBlur || o.isDisabled() || o.onBlur.call(o, {
                event: a
            })
        }
        function l(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onClick || o.isDisabled() || o.onClick.call(o, {
                event: a
            })
        }
        function m(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onChange || o.isDisabled() || o.onChange.call(o, {
                event: a
            })
        }
        function n(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onKeydown || o.isDisabled() || o.onKeydown.call(o, {
                event: a
            })
        }
        var o = this,
            p = b.Template,
            q = null,
            r = null,
            s = "sc-checkbox_disabled",
            t = {
                name: "uiCheckboxTpl",
                text: '<span class="sc-checkbox-wrapper <%=extraClass%>" style="<%=style%>"><input id="<%=checkboxId%>" name="<%=name%>" class="sc-input-checkbox sc-focusable" value="<%=value%>" type="checkbox" <%=checked%> <%=disabled%> /><label for="<%=checkboxId%>"><%=labelText%></label></span>'
            };
        this.id = c.id || a.Dialog.getNextId("sc-checkbox_"), this.name = c.name || "", this.type = c.type, this.value = c.value || "", this.storable = !! c.storable, this.storedValue = !! c.checked, this.label = c.label || "", this.style = c.style || "", this.extraClass = c.extraClass || "", this.onLoad = c.onLoad, this.onShow = c.onShow, this.onHide = c.onHide, this.onFocus = c.onFocus, this.onBlur = c.onBlur, this.onClick = c.onClick, this.onChange = c.onChange, this.onKeydown = c.onKeydown, this.dialog = e, this.getInputElement = function() {
            return r
        }, this.check = function() {
            this.isDisabled() || (r.checked = !0)
        }, this.uncheck = function() {
            this.isDisabled() || (r.checked = !1)
        }, this.isChecked = function() {
            return r.checked
        }, this.setValue = function(a) {
            this.isDisabled() || (r.value = a)
        }, this.getValue = function() {
            return r.value
        }, this.enable = function() {
            d.removeClass(q, s), r.disabled = !1
        }, this.disable = function() {
            d.addClass(q, s), r.disabled = !0
        }, this.isDisabled = function() {
            return d.hasClass(q, s) && r.disabled
        }, this.commit = function() {
            this.storedValue = this.isChecked()
        }, this.reset = function() {
            this[this.storedValue ? "check" : "uncheck"](), this.commit()
        }, this.isChanged = function() {
            return this.storedValue !== this.isChecked()
        }, this.destroy = function() {
            e.unsubscribe("onLoad", this), e.unsubscribe("onShow", this), e.unsubscribe("onHide", this), e.unsubscribe("onClose", this), i(), d.remove(q);
            for (var a in this) this.hasOwnProperty(a) && delete this[a]
        }, f()
    });
    a.Checkbox = e, a.registerUIElement("checkbox", e)
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(e, f) {
        function g() {
            "function" == typeof i.onLoad && f.subscribe("onLoad", i.onLoad, i), "function" == typeof i.onShow && f.subscribe("onShow", i.onShow, i), "function" == typeof i.onHide && f.subscribe("onHide", i.onHide, i), h()
        }
        function h() {
            var a = "";
            j.create(l.name, l.text), a = j.render(l.name, {
                extraClass: i.extraClass,
                style: i.style
            }), i.element = k = d.create(a)[0], j.create(m.name, m.text), d.each(i.childrenDefinitions, function(a, b) {
                i.addChild(b)
            })
        }
        var i = this,
            j = b.Template,
            k = null,
            l = {
                name: "uiVContainerTpl",
                text: '<div class="sc-vbox <%=extraClass%>" style="<%=style%>"></div>'
            },
            m = {
                name: "uiVContainerChildTpl",
                text: '<div class="sc-vbox-child"></div>'
            },
            n = {};
        this.id = e.id || a.Dialog.getNextId("sc-vbox_"), this.type = e.type, this.style = e.style || "", this.extraClass = e.extraClass || "", this.widths = c.is(e.widths, "Array") ? e.widths : [], this.childrenDefinitions = e.children || [], this.onLoad = e.onLoad, this.onShow = e.onShow, this.onHide = e.onHide, this.dialog = f, this.addChild = function(b) {
            var c = j.render(m.name, {}),
                e = d.create(c)[0],
                g = a.createUIElement(b.type, b, f);
            if (!g) throw new Error('Unable to create UI element with type "' + b.type + '". No such element.');
            n[g.id] = g, g.appendTo(e);
            var h = this.getIndexOfChild(g.id),
                i = this.widths[h] || "";
            return d.css(e, {
                width: i
            }), d.appendTo(e, k), g
        }, this.removeChild = function(a) {
            var b = n[a],
                c = !1;
            return b && (b.destroy(), delete n[a], c = !0), c
        }, this.getChildren = function() {
            return n
        }, this.getIndexOfChild = function(a) {
            for (var b = -1, d = c.getKeys(n), e = 0, f = d.length; f > e; e++) if (d[e] === a) {
                b = e;
                break
            }
            return b
        }, this.disable = function() {
            for (var a in n)"function" == typeof a.disable && a.disable()
        }, this.enable = function() {
            for (var a in n)"function" == typeof a.enable && a.enable()
        }, this.destroy = function() {
            f.unsubscribe("onLoad", this), f.unsubscribe("onShow", this), f.unsubscribe("onHide", this);
            for (var a in n) i.removeChild(a.id);
            d.remove(k);
            for (var b in this) this.hasOwnProperty(b) && delete this[b]
        }, g()
    });
    a.VerticalContainer = e, a.registerUIElement("vbox", e)
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(e, f) {
        function g() {
            "function" == typeof i.onLoad && f.subscribe("onLoad", i.onLoad, i), "function" == typeof i.onShow && f.subscribe("onShow", i.onShow, i), "function" == typeof i.onHide && f.subscribe("onHide", i.onHide, i), h()
        }
        function h() {
            var a = "";
            j.create(l.name, l.text), a = j.render(l.name, {
                extraClass: i.extraClass,
                style: i.style
            }), i.element = k = d.create(a)[0], j.create(m.name, m.text), d.each(i.childrenDefinitions, function(a, b) {
                i.addChild(b)
            })
        }
        var i = this,
            j = b.Template,
            k = null,
            l = {
                name: "uiHContainerTpl",
                text: '<div class="sc-hbox <%=extraClass%>" style="<%=style%>"></div>'
            },
            m = {
                name: "uiHContainerChildTpl",
                text: '<div class="sc-hbox-child"></div>'
            },
            n = {};
        this.id = e.id || a.Dialog.getNextId("sc-hbox_"), this.type = e.type, this.style = e.style || "", this.extraClass = e.extraClass || "", this.widths = c.is(e.widths, "Array") ? e.widths : [], this.childrenDefinitions = e.children || [], this.onLoad = e.onLoad, this.onShow = e.onShow, this.onHide = e.onHide, this.dialog = f, this.addChild = function(b) {
            var c = j.render(m.name, {}),
                e = d.create(c)[0],
                g = a.createUIElement(b.type, b, f);
            if (!g) throw new Error('Unable to create UI element with type "' + b.type + '". No such element.');
            n[g.id] = g, g.appendTo(e);
            var h = this.getIndexOfChild(g.id),
                i = this.widths[h] || "";
            return d.css(e, {
                width: i
            }), d.appendTo(e, k), g
        }, this.removeChild = function(a) {
            var b = n[a],
                c = !1;
            return b && (b.destroy(), delete n[a], c = !0), c
        }, this.getChildren = function() {
            return n
        }, this.getIndexOfChild = function(a) {
            for (var b = -1, d = c.getKeys(n), e = 0, f = d.length; f > e; e++) if (d[e] === a) {
                b = e;
                break
            }
            return b
        }, this.disable = function() {
            for (var a in n)"function" == typeof a.disable && a.disable()
        }, this.enable = function() {
            for (var a in n)"function" == typeof a.enable && a.enable()
        }, this.destroy = function() {
            f.unsubscribe("onLoad", this), f.unsubscribe("onShow", this), f.unsubscribe("onHide", this);
            for (var a in n) i.removeChild(a.id);
            d.remove(k);
            for (var b in this) this.hasOwnProperty(b) && delete this[b]
        }, g()
    });
    a.HorizontalContainer = e, a.registerUIElement("hbox", e)
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(e, f) {
        function g() {
            f.subscribe("onLoad", function(a) {
                a.sender.dialogName === f.dialogName && (i(), "function" == typeof l.onLoad && l.onLoad.call(l, a))
            }, l), "function" == typeof l.onShow && f.subscribe("onShow", l.onShow, l), "function" == typeof l.onHide && f.subscribe("onHide", l.onHide, l), h()
        }
        function h() {
            var a = "";
            m.create(o.name, o.text), a = m.render(o.name, {
                extraClass: l.extraClass,
                style: l.style
            }), l.element = n = d.create(a)[0], m.create(p.name, p.text), d.each(l.childrenDefinitions, function(a, b) {
                l.addChild(b)
            })
        }
        function i() {
            f.subscribe({
                eventType: "click",
                element: n,
                handler: k
            })
        }
        function j() {
            f.unsubscribe({
                eventType: "click",
                element: n,
                handler: k
            })
        }
        function k(a) {
            a.preventDefault(), "function" == typeof l.onClick && l.onClick.call(l, {
                event: a
            })
        }
        var l = this,
            m = b.Template,
            n = null,
            o = {
                name: "uiItemListTpl",
                text: '<div class="sc-item-list <%=extraClass%>" style="<%=style%>"></div>'
            },
            p = {
                name: "uiItemListChildTpl",
                text: '<div class="sc-item-list-child" data-ud-word="<%=itemText%>"><span class="sc-item-list__text"><%=itemText%></span><a class="sc-item-list__icon sc-item-list__icon_close sc-focusable" href="javascript:void(0)" title="<%=title%>" role="button" aria-label="<%=title%>"></a></div>'
            },
            q = [],
            r = !1;
        this.id = e.id || a.Dialog.getNextId("sc-item-list_"), this.type = e.type, this.title = e.title || "", this.style = e.style || "", this.extraClass = e.extraClass || "", this.childrenDefinitions = e.children || [], this.onLoad = e.onLoad, this.onShow = e.onShow, this.onHide = e.onHide, this.onClick = e.onClick, this.dialog = f, this.addChild = function(a, b) {
            var c = m.render(p.name, {
                    itemText: a,
                    title: l.title
                }),
                e = d.create(c)[0];
            q.push(a), b ? d.prependTo(e, n) : d.appendTo(e, n)
        }, this.removeChild = function(a, b) {
            q.splice(c.indexOf(q, b), 1), n.removeChild(a)
        }, this.removeAllChild = function() {
            q = [], n.innerHTML = ""
        }, this.inChildren = function(a) {
            return c.inArray(q, a)
        }, this.block = function() {
            r = !0
        }, this.unblock = function() {
            r = !1
        }, this.isBlocked = function() {
            return r
        }, this.destroy = function() {
            f.unsubscribe("onLoad", this), f.unsubscribe("onShow", this), f.unsubscribe("onHide", this), j(), d.remove(n);
            for (var a in this) this.hasOwnProperty(a) && delete this[a]
        }, g()
    });
    a.ItemList = e, a.registerUIElement("itemList", e)
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(c, e) {
        function f() {
            e.subscribe("onLoad", function(a) {
                a.sender.dialogName === e.dialogName && (h(), "function" == typeof o.onLoad && o.onLoad.call(o, a))
            }, o), "function" == typeof o.onShow && e.subscribe("onShow", o.onShow, o), "function" == typeof o.onHide && e.subscribe("onHide", o.onHide, o), o.storable && (e.subscribe("onSubmit", function(a) {
                a.sender.dialogName === e.dialogName && o.commit()
            }, o), e.subscribe("onClose", function(a) {
                a.sender.dialogName === e.dialogName && o.reset()
            }, o), e.subscribe("onCancel", function(a) {
                a.sender.dialogName === e.dialogName && o.reset()
            }, o)), o.element = q = g()
        }
        function g() {
            var a = "",
                b = null;
            return p.create(t.name, t.text), a = p.render(t.name, {
                inputId: o.id,
                name: o.name,
                value: o.value,
                labelText: o.label,
                placeholder: o.placeholder,
                maxLength: o.maxLength,
                disabled: c.disabled ? "disabled" : "",
                style: o.style,
                extraClass: o.extraClass
            }), b = d.create(a)[0], r = d.find("input", b)[0], b
        }
        function h() {
            e.subscribe({
                eventType: "focus",
                element: r,
                handler: j
            }), e.subscribe({
                eventType: "blur",
                element: r,
                handler: k
            }), e.subscribe({
                eventType: "click",
                element: r,
                handler: l
            }), e.subscribe({
                eventType: "change",
                element: r,
                handler: m
            }), e.subscribe({
                eventType: "keydown",
                element: r,
                handler: n
            })
        }
        function i() {
            e.unsubscribe({
                eventType: "focus",
                element: r,
                handler: j
            }), e.unsubscribe({
                eventType: "blur",
                element: r,
                handler: k
            }), e.unsubscribe({
                eventType: "click",
                element: r,
                handler: l
            }), e.unsubscribe({
                eventType: "change",
                element: r,
                handler: m
            }), e.unsubscribe({
                eventType: "keydown",
                element: r,
                handler: n
            })
        }
        function j(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onFocus || o.isDisabled() || o.onFocus.call(o, {
                event: a
            })
        }
        function k(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onBlur || o.isDisabled() || o.onBlur.call(o, {
                event: a
            })
        }
        function l(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onClick || o.isDisabled() || o.onClick.call(o, {
                event: a
            })
        }
        function m(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onChange || o.isDisabled() || o.onChange.call(o, {
                event: a
            })
        }
        function n(a) {
            o.isDisabled() && a.preventDefault(), "function" != typeof o.onKeydown || o.isDisabled() || o.onKeydown.call(o, {
                event: a
            })
        }
        var o = this,
            p = b.Template,
            q = null,
            r = null,
            s = "sc-input-text_disabled",
            t = {
                name: "uiTextInputTpl",
                text: '<div class="sc-text-input-wrapper <%=extraClass%>" style="<%=style%>"><label for="<%=inputId%>" id="sc-label_<%=inputId%>"><%=placeholder%></label><div class="sc-text-input-holder"><input id="<%=inputId%>" name="<%=name%>" maxlength="<%=maxLength%>" class="sc-input-text sc-focusable" type="text" placeholder="<%=placeholder%>" value="<%=value%>" <%=disabled%> autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" aria-labelledby="sc-label_<%=inputId%>" /></div></div>'
            };
        this.id = c.id || a.Dialog.getNextId("sc-text-input_"), this.name = c.name || "", this.type = c.type, this.value = c.value || "", this.storable = !! c.storable, this.storedValue = this.value, this.label = c.label || "", this.placeholder = c.placeholder || "", this.maxLength = c.maxLength || "", this.style = c.style || "", this.extraClass = c.extraClass || "", this.onLoad = c.onLoad, this.onShow = c.onShow, this.onHide = c.onHide, this.onFocus = c.onFocus, this.onBlur = c.onBlur, this.onClick = c.onClick, this.onChange = c.onChange, this.onKeydown = c.onKeydown, this.dialog = e, this.getValue = function() {
            return r.value
        }, this.setValue = function(a) {
            this.isDisabled() || (r.value = a)
        }, this.enable = function() {
            d.removeClass(q, s), r.disabled = !1
        }, this.disable = function() {
            d.addClass(q, s), r.disabled = !0
        }, this.isDisabled = function() {
            return d.hasClass(r, s) && r.disabled
        }, this.commit = function() {
            this.storedValue = this.getValue()
        }, this.reset = function() {
            this.setValue(this.storedValue), this.commit()
        }, this.isChanged = function() {
            return this.storedValue !== this.getValue()
        }, this.destroy = function() {
            e.unsubscribe("onLoad", this), e.unsubscribe("onShow", this), e.unsubscribe("onHide", this), e.unsubscribe("onSubmit", this), e.unsubscribe("onClose", this), e.unsubscribe("onCancel", this), i(), d.remove(q);
            for (var a in this) this.hasOwnProperty(a) && delete this[a]
        }, f()
    });
    a.TextInput = e, a.registerUIElement("text", e)
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(c, e) {
        function f() {
            "function" == typeof h.onLoad && e.subscribe("onLoad", h.onLoad, h), "function" == typeof h.onShow && e.subscribe("onShow", h.onShow, h), "function" == typeof h.onHide && e.subscribe("onHide", h.onHide, h), h.element = j = g()
        }
        function g() {
            var a = "";
            return i.create(k.name, k.text), a = i.render(k.name, {
                html: h.html,
                style: h.style,
                extraClass: h.extraClass
            }), d.create(a)[0]
        }
        var h = this,
            i = b.Template,
            j = null,
            k = {
                name: "uiHtmlTpl",
                text: '<div class="sc-html <%=extraClass%>" style="<%=style%>"><%=html%></div>'
            };
        this.id = c.id || a.Dialog.getNextId("sc-html_"), this.type = c.type, this.html = c.html || "", this.style = c.style || "", this.extraClass = c.extraClass || "", this.onLoad = c.onLoad, this.onShow = c.onShow, this.onHide = c.onHide, this.dialog = e, this.setHtml = function(a) {
            d.html(j, a)
        }, this.getHtml = function() {
            return d.html(j)
        }, this.destroy = function() {
            e.unsubscribe("onLoad", this), e.unsubscribe("onShow", this), e.unsubscribe("onHide", this), d.remove(j);
            for (var a in this) this.hasOwnProperty(a) && delete this[a]
        }, f()
    });
    a.HtmlContainer = e, a.registerUIElement("html", e)
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = b.Utils,
        d = b.UILib;
    a = a || {};
    var e = c.extend(a.Component, function(c, e) {
        function f() {
            e.subscribe("onLoad", function(a) {
                a.sender.dialogName === e.dialogName && (h(), "function" == typeof n.onLoad && n.onLoad.call(n, a))
            }, n), "function" == typeof n.onShow && e.subscribe("onShow", n.onShow, n), "function" == typeof n.onHide && e.subscribe("onHide", n.onHide, n), n.element = p = g()
        }
        function g() {
            var a = "";
            return o.create(r.name, r.text), a = o.render(r.name, {
                id: n.id,
                buttonHtml: n.text,
                title: n.title,
                label: n.label,
                href: n.href,
                target: n.target,
                buttonStyle: n.style,
                extraClass: c.disabled ? q + " " + n.extraClass : n.extraClass
            }), d.create(a)[0]
        }
        function h() {
            e.subscribe({
                eventType: "focus",
                element: p,
                handler: j
            }), e.subscribe({
                eventType: "blur",
                element: p,
                handler: k
            }), e.subscribe({
                eventType: "click",
                element: p,
                handler: l
            }), e.subscribe({
                eventType: "keydown",
                element: p,
                handler: m
            })
        }
        function i() {
            e.unsubscribe({
                eventType: "focus",
                element: p,
                handler: j
            }), e.unsubscribe({
                eventType: "blur",
                element: p,
                handler: k
            }), e.unsubscribe({
                eventType: "click",
                element: p,
                handler: l
            }), e.unsubscribe({
                eventType: "keydown",
                element: p,
                handler: m
            })
        }
        function j(a) {
            n.isDisabled() && a.preventDefault(), "function" != typeof n.onFocus || n.isDisabled() || n.onFocus.call(n, {
                event: a
            })
        }
        function k(a) {
            n.isDisabled() && a.preventDefault(), "function" != typeof n.onBlur || n.isDisabled() || n.onBlur.call(n, {
                event: a
            })
        }
        function l(a) {
            (!n.href || "#" === n.href || n.isDisabled()) && a.preventDefault(), "function" != typeof n.onClick || n.isDisabled() || n.onClick.call(n, {
                event: a
            })
        }
        function m(a) {
            n.isDisabled() && a.preventDefault(), "function" != typeof n.onKeydown || n.isDisabled() || n.onKeydown.call(n, {
                event: a
            })
        }
        var n = this,
            o = b.Template,
            p = null,
            q = "sc-button_disabled",
            r = {
                name: "uiButtonTpl",
                text: '<a class="sc-button sc-focusable <%=extraClass%>" href="<%=href%>" title="<%=title%>" style="<%=buttonStyle%>" target="<%=target%>" role="button" aria-labelledby="sc-label_<%=id%>"><%=buttonHtml%><span id="sc-label_<%=id%>" aria-hidden="false" style="display: none; cursor: default; color: transparent;"><%=label%></span><a/>'
            };
        this.id = c.id || a.Dialog.getNextId("sc-button_"), this.type = c.type, this.text = c.text || this.id, this.title = c.title || "", this.label = "&#65279;" === this.text ? this.title : "", this.href = c.href || "#", this.target = c.target || "", this.style = c.style || "", this.extraClass = c.extraClass || "", this.onLoad = c.onLoad, this.onShow = c.onShow, this.onHide = c.onHide, this.onFocus = c.onFocus, this.onBlur = c.onBlur, this.onClick = c.onClick, this.onKeydown = c.onKeydown, this.dialog = e, this.click = function() {
            e.fire({
                eventType: "click",
                element: p
            })
        }, this.enable = function() {
            d.removeClass(p, q)
        }, this.disable = function() {
            d.addClass(p, q)
        }, this.isDisabled = function() {
            return d.hasClass(p, q)
        }, this.destroy = function() {
            e.unsubscribe("onLoad", this), e.unsubscribe("onShow", this), e.unsubscribe("onHide", this), i(), d.remove(p);
            for (var a in this) this.hasOwnProperty(a) && delete this[a]
        }, f()
    });
    a.Button = e, a.registerUIElement("button", e)
}(SCAYT.UI, SCAYT.prototype), SCAYT.UI = SCAYT.UI || {}, function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b, this.menuTemplate = '<div tabindex="0" class="sc-cm-holder <%=extraMainClass%>"><ul class="sc-cm"></ul></div>', this.menuItemTemplate = '<li class="sc-cm__item <%=extraItemClass%>"><a href="javascript: void(0);" class="clrfix" title="<%=innerText%>"><i class="i-icon i-icon_<%=itemName%>"></i><span class="shortcut"><%=shortcutText%></span><%=innerText%></a></li>', this.menuSeparatorTemplate = '<li class="sc-cm__item sc-cm__item_separator"></li>', this.isMacOS = this.sandbox.Utils.browser.mac, this.shortcuts = {
            undo: (this.isMacOS ? "&#8984;" : "Ctrl") + "+Z",
            redo: (this.isMacOS ? "&#8984;" : "Ctrl") + "+Shift+Z",
            copy: (this.isMacOS ? "&#8984;" : "Ctrl") + "+C",
            paste: (this.isMacOS ? "&#8984;" : "Ctrl") + "+V",
            cut: (this.isMacOS ? "&#8984;" : "Ctrl") + "+X"
        }, this.appendTo = "body", this.attachTo = this.sandbox.getOption("container")
    };
    b.prototype = {
        init: function() {
            this.sandbox.UILib;
            this.menu = new b.Menu(this.sandbox, this.menuTemplate, this.menuItemTemplate, this.shortcutText, this.menuSeparatorTemplate, this.shortcuts, this.appendTo, this.attachTo), this.hide()
        },
        show: function() {
            this.menu.show()
        },
        hide: function() {
            this.menu.hide()
        },
        addItem: function(a, b) {
            this.menu.addItem(a, b)
        },
        addItems: function(a) {
            this.menu.addItems(a)
        },
        addGroup: function(a, b) {
            this.menu.addGroup(a, b)
        },
        removeItem: function(a) {
            return this.menu.removeItem(a)
        },
        getItem: function(a) {
            return this.menu.getItem(a)
        },
        clear: function() {
            this.menu.clear()
        },
        getDOMElement: function() {
            return this.menu.getDOMElement()
        }
    }, b.Menu = function(a, c, d, e, f, g, h, i, j) {
        function k() {
            var a;
            return L.sandbox.Template.create("cmMenuTpl", L.menuTemplate), a = L.sandbox.Template.render("cmMenuTpl", {
                extraMainClass: L.extraClass || ""
            }), L.sandbox.Template.remove("cmMenuTpl"), M.appendTo(a, L.appendTo)
        }
        function l() {
            var a = L.selectedIndex - 1;
            return 0 > a && (a = L.sortedItems.length - 1), L.selectItem(a), !0
        }
        function m() {
            var a = L.selectedIndex + 1;
            return a >= L.sortedItems.length && (a = 0), L.selectItem(a), !0
        }
        function n() {
            var a = P[L.sortedItems[L.selectedIndex].itemName];
            return a.childElement ? (L.keyboardNavigation.deActivate(), a.childElement.show()) : a.click(), !0
        }
        function o() {
            var b = P[L.sortedItems[L.selectedIndex].itemName];
            return b.parentElement.isSubmenu ? b.parentElement.hide() : a.fire("restoreSelection"), !0
        }
        function p(a) {
            a.sort(function(a, b) {
                return a.groupOrder < b.groupOrder ? -1 : a.groupOrder > b.groupOrder ? 1 : a.order < b.order ? -1 : a.order > b.order ? 1 : 0
            })
        }
        function q() {
            L.sandbox.subscribe(L.sandbox.getOption("isTouchDevice") ? {
                eventType: "orientationchange",
                element: window,
                handler: s
            } : {
                eventType: "resize",
                element: window,
                handler: s
            }), L.isSubmenu ? (L.sandbox.subscribe({
                eventType: "mouseenter",
                element: L.appendTo,
                handler: C
            }), L.sandbox.subscribe({
                eventType: "mouseleave",
                element: L.appendTo,
                handler: D
            })) : (T && L.sandbox.subscribe({
                eventType: "touchstart",
                element: L.attachTo,
                handler: w
            }), V ? (L.sandbox.subscribe({
                eventType: "mouseover",
                element: L.attachTo,
                handler: x
            }), L.sandbox.subscribe({
                eventType: "mouseout",
                element: L.attachTo,
                handler: y
            }), L.sandbox.subscribe({
                eventType: "mouseenter",
                element: L.menuContainer[0],
                handler: z
            }), L.sandbox.subscribe({
                eventType: "mouseleave",
                element: L.menuContainer[0],
                handler: z
            }), L.sandbox.subscribe({
                eventType: "keydown",
                element: document,
                handler: A
            }), L.sandbox.subscribe({
                eventType: "click",
                element: L.attachTo,
                handler: A
            }), L.sandbox.subscribe({
                eventType: "onShow",
                handler: B
            }), L.sandbox.subscribe({
                eventType: "restoreSelection",
                handler: A
            })) : L.sandbox.subscribe({
                eventType: "contextmenu",
                element: L.attachTo,
                handler: u
            }))
        }
        function r() {
            L.sandbox.unsubscribe(L.sandbox.getOption("isTouchDevice") ? {
                eventType: "orientationchange",
                element: window,
                handler: s
            } : {
                eventType: "resize",
                element: window,
                handler: s
            }), L.isSubmenu ? (L.sandbox.unsubscribe({
                eventType: "mouseenter",
                element: L.appendTo,
                handler: C
            }), L.sandbox.unsubscribe({
                eventType: "mouseleave",
                element: L.appendTo,
                handler: D
            })) : (T && L.sandbox.unsubscribe({
                eventType: "touchstart",
                element: L.attachTo,
                handler: w
            }), L.sandbox.subscribe({
                eventType: "blur",
                element: L.attachTo,
                handler: L.focusInput
            }), V ? (L.sandbox.unsubscribe({
                eventType: "mouseover",
                element: L.attachTo,
                handler: x
            }), L.sandbox.unsubscribe({
                eventType: "mouseout",
                element: L.attachTo,
                handler: y
            }), L.sandbox.unsubscribe({
                eventType: "mouseenter",
                element: L.menuContainer[0],
                handler: z
            }), L.sandbox.unsubscribe({
                eventType: "mouseleave",
                element: L.menuContainer[0],
                handler: z
            }), L.sandbox.unsubscribe({
                eventType: "keydown",
                element: document,
                handler: A
            }), L.sandbox.unsubscribe({
                eventType: "click",
                element: L.attachTo,
                handler: A
            }), L.sandbox.unsubscribe({
                eventType: "onShow",
                handler: B
            }), L.sandbox.unsubscribe({
                eventType: "restoreSelection",
                handler: A
            })) : L.sandbox.unsubscribe({
                eventType: "contextmenu",
                element: L.attachTo,
                handler: u
            }))
        }
        function s() {
            this.hide()
        }
        function t(a) {
            var b, c = {
                clientX: a.clientX || null,
                clientY: a.clientY || null,
                pageX: a.pageX || null,
                pageY: a.pageY || null
            };
            setTimeout(function() {
                L.clearPosition(), L.show(), b = F(c), L.setPosition(b.x, b.y)
            }, 0)
        }
        function u(a) {
            var b, c, d, e;
            L.sandbox.getOption("paused") || (L.sandbox.Utils.browser.gecko && (b = L.sandbox.getSelection(), d = b.getRangeAt(0), c = L.sandbox.getCaretRangeFromEvent(a), d.containsRange(c) === !1 && (b.removeAllRanges(), b.addRange(c))), e = L.sandbox.getScaytNodeFromSelection(), e || (e = L.sandbox.getGraytNodeFromSelection()), (e || !U) && (a.preventDefault(), t(a)))
        }
        function v() {
            var a, b = L.sandbox.getSelection(),
                c = H(b);
            L.sandbox.getOption("paused") || (a = L.sandbox.getScaytNodeFromSelection(), a || (a = L.sandbox.getGraytNodeFromSelection()), (a || !U) && t({
                clientX: c.x,
                clientY: c.y
            }))
        }
        function w(a) {
            var b, c, d = (new Date).getTime(),
                e = L.sandbox.getOption("misspelled_word_node"),
                f = L.sandbox.getOption("data_attribute_name"),
                g = L.sandbox.createRange(),
                h = window.pageXOffset,
                i = window.pageYOffset;
            if (!L.sandbox.getOption("paused")) {
                if (c = L.sandbox.Utils.isEqualNode(a.target, f) ? a.target : L.sandbox.DOM.findNodeParents(a.target, e, f)[0], d - X.time > W || !c || c !== X.scaytNode) return X.time = d, X.event = a, void(X.scaytNode = c);
                a.preventDefault(), L.sandbox.fire({
                    eventType: "focus",
                    element: L.attachTo
                }), window.scrollTo(h, i), g.selectNodeContents(c), b = L.sandbox.getSelection(), b.removeAllRanges(), b.addRange(g), t({
                    clientX: a.targetTouches[0].clientX,
                    clientY: a.targetTouches[0].clientY,
                    pageX: a.targetTouches[0].pageX,
                    pageY: a.targetTouches[0].pageY
                })
            }
        }
        function x(a) {
            var b, c = a.target,
                d = L.sandbox.getOption("misspelled_word_class"),
                e = L.sandbox.getOption("problem_grammar_class");
            if (!L.sandbox.getOption("paused")) {
                for (; c !== L.attachTo;) {
                    if (M.hasClass(c, d)) {
                        b = !0;
                        break
                    }
                    if (M.hasClass(c, e)) {
                        b = !1;
                        break
                    }
                    c = c.parentNode
                }
                c !== L.attachTo && c !== Y && (!L.hidden && A(), Y = c, M.addClass(Y, "problem-word_hover"), clearTimeout(J), clearTimeout(K), J = setTimeout(function() {
                    t(a)
                }, 500))
            }
        }
        function y(a) {
            var b = a.relatedTarget || a.toElement;
            if (Y) {
                if (b) for (; b;) {
                    if (b === Y || b === L.menuContainer[0]) return;
                    b = b.parentNode
                }
                Y = null, L.hidden && B(), clearTimeout(J), K = setTimeout(function() {
                    !Z && A()
                }, 1e3)
            }
        }
        function z() {
            Z = !Z, Z || A()
        }
        function A() {
            L.hidden || (L.hide(), B())
        }
        function B() {
            var a = M.find(".problem-word_hover", L.attachTo);
            if (a.length) for (var b = 0; b < a.length; b++) M.removeClass(a[b], "problem-word_hover")
        }
        function C() {
            var a;
            L.clearPosition(), L.show(), a = F(), L.setPosition(a.x, a.y)
        }
        function D() {
            L.hide()
        }
        function E() {
            L.hide()
        }
        function F(a) {
            var b, c, d, e, f = {
                    x: 0,
                    y: 0
                },
                g = 0,
                h = 0,
                i = N.getScrollLeft(),
                j = N.getScrollTop(),
                k = N.getWindowWidth(),
                l = N.getWindowHeight(),
                m = M.outerWidth(R),
                n = M.outerHeight(R),
                o = N.getDocumentHeight(),
                p = L.sandbox.getOption("documentContainer"),
                q = L.sandbox.getOption("isIframe"),
                r = L.sandbox.getOption("isTouchDevice");
            return b = q && r ? G(p) : p.getBoundingClientRect(), L.isSubmenu ? (c = M.outerWidth(L.appendTo), d = M.outerHeight(L.appendTo), e = M.offset(L.appendTo), f.x = c, f.y = 0, e.left + c + m > i + k && (f.x -= e.left + c + m - (i + k)), e.top + n > j + l && (f.y -= e.top + n - (j + l), e.top + f.y < j && (f.y = o >= j + n ? j - e.top : o - n - e.top))) : (a.pageX && a.pageY ? (g = q ? a.clientX + i + b.left : a.pageX, h = q ? a.clientY + j + b.top : a.pageY) : (g = a.clientX + i + (q ? b.left : 0), h = a.clientY + j + (q ? b.top : 0)), f.x = g, f.y = h, g + m > k + i && (f.x = g - m, f.x < i && (f.x = i)), h + n > l + j && (f.y = h - n, f.y < j && (f.y = o >= j + n ? j : o - n))), f
        }
        function G(a) {
            for (var b = 0, c = 0; a;) b += parseInt(a.offsetTop - a.scrollTop + a.clientTop), c += parseInt(a.offsetLeft - a.scrollLeft + a.clientLeft), a = a.offsetParent;
            return {
                top: b,
                left: c
            }
        }
        function H(a) {
            var b = a.getRangeAt(0).cloneRange(),
                c = document.createElement("span"),
                d = {
                    x: 0,
                    y: 0
                },
                e = {};
            return b.collapse(!0), c.appendChild(document.createTextNode("​")), b.insertNode(c), e = c.getBoundingClientRect(), d.x = e.left, d.y = e.bottom, c.parentNode.removeChild(c), d
        }
        function I() {
            var a;
            L.sandbox.Template.create("cmMenuSeparatorTpl", L.menuSeparatorTemplate), a = L.sandbox.Template.render("cmMenuSeparatorTpl", {}), M.appendTo(a, S)
        }
        var J, K, L = this,
            M = a.UILib,
            N = SCAYT.UIMetrics,
            O = SCAYT.UI.KeyboardNavigation,
            P = {},
            Q = {
                "default": 100
            },
            R = null,
            S = null,
            T = a.getOption("enableOnTouchDevices"),
            U = a.getOption("contextMenuForMisspelledOnly"),
            V = a.getOption("contextMenuByMouseover"),
            W = 300,
            X = {
                time: 0,
                event: {},
                scaytNode: null
            },
            Y = null,
            Z = !1;
        this.sandbox = a, this.menuTemplate = c, this.menuItemTemplate = d, this.menuSeparatorTemplate = f, this.shortcuts = g, this.appendTo = h, this.attachTo = M.find(i)[0], this.extraClass = j, this.isSubmenu = !this.attachTo, this.sortedItems = [], this.selectedIndex = -1, this.hidden = this.isSubmenu ? !0 : !1, this.menuContainer = R = k(), L.sandbox.subscribe({
            eventType: "contextmenu",
            element: R[0],
            handler: function(a) {
                a.preventDefault()
            }
        }), S = M.find(".sc-cm", R), q(), this.keyboardNavigation = new O(document, {
            38: l,
            40: m,
            9: m,
            37: o,
            39: n,
            32: n,
            13: n,
            27: o
        }, this.sandbox), this.sandbox.subscribe("allModulesReady", function() {
            !V && this.sandbox.fire("setShortcuts", {
                shortcuts: [{
                    shortcut: SCAYT.SHIFT + 121,
                    callback: v,
                    context: L
                }]
            })
        }), this.show = function() {
            if (this.hidden !== !1) {
                this.sortedItems = [], this.selectedIndex = -1;
                var a = this;
                this.clear(), this.isSubmenu || this.sandbox.fire("beforeContextMenuShow", {
                    problemNode: Y
                });
                for (var b in P) this.sortedItems.push({
                    itemName: P[b].itemName,
                    groupOrder: Q[P[b].group],
                    groupName: P[b].group,
                    order: P[b].order
                });
                p(this.sortedItems);
                for (var c = this.sortedItems.length, d = c && this.sortedItems[0].groupName, e = 0; c > e; e++) d != this.sortedItems[e].groupName && "moresuggest" != this.sortedItems[e].groupName && (I(), d = this.sortedItems[e].groupName), P[this.sortedItems[e].itemName].appendTo(S);
                M.addClass(R, "sc-cm_show"), M.removeClass(R, "sc-cm_hide"), this.isSubmenu || V || (this.sandbox.unsubscribe({
                    eventType: "blur",
                    element: R[0],
                    handler: E
                }), this.sandbox.subscribe({
                    eventType: "blur",
                    element: R[0],
                    handler: E
                }), setTimeout(function() {
                    a.sandbox.fire({
                        eventType: "focus",
                        element: R[0]
                    })
                }, 0)), this.hidden = !1, this.selectItem(0), V || (this.isSubmenu && this.parentElement.parentElement.keyboardNavigation.deActivate(), this.keyboardNavigation.activate())
            }
        }, this.hide = function() {
            var a = this.getVisibleSubmenu();
            a && a.hide(), this.hidden || (M.addClass(R, "sc-cm_hide"), M.removeClass(R, "sc-cm_show"), this.removeActive(), this.isSubmenu || V || this.sandbox.subscribe({
                eventType: "blur",
                element: R[0],
                handler: E
            }), this.hidden = !0, this.isSubmenu || this.sandbox.fire("contextMenuHide", {}), V || (this.keyboardNavigation.deActivate(), this.isSubmenu && !this.parentElement.parentElement.hidden && this.parentElement.parentElement.keyboardNavigation.activate()))
        }, this.addItem = function(a, c) {
            "undefined" == typeof c.group && (c.group = "default"), "undefined" != typeof Q[c.group] && (P[a] = new b.MenuItem(this, a, c))
        }, this.addItems = function(a) {
            for (var b in a) this.addItem(b, a[b])
        }, this.addGroup = function(a, b) {
            Q[a] = "number" == typeof b ? b : 100
        }, this.removeItem = function(a) {
            var b = !1;
            return a && P[a] && (P[a].destroy(), delete P[a], b = !0), b
        }, this.getItem = function(a) {
            var b = P[a];
            if (!b) for (var c in P) if (P[c].childElement && (b = P[c].childElement.getItem(a)), b) break;
            return b
        }, this.getVisibleSubmenu = function() {
            var a, b = null;
            for (var c in P) if (a = P[c].childElement, a && !a.hidden) {
                b = a;
                break
            }
            return b
        }, this.selectItem = function(a) {
            var b = this.sortedItems[a];
            b && (P[b.itemName].setActive(), this.selectedIndex = a)
        }, this.clear = function() {
            if (!this.isSubmenu) for (var a in P) this.removeItem(a);
            M.empty(S)
        }, this.setPosition = function(a, b) {
            M.setPosition(R, a, b)
        }, this.clearPosition = function() {
            M.css(R, {
                left: -9999,
                top: -9999
            })
        }, this.getDOMElement = function() {
            return R
        }, this.destroy = function() {
            this.clear(), r(), M.remove(R)
        }, this.removeActive = function() {
            var a = M.find(".sc-cm__item_active", this.getDOMElement())[0];
            M.removeClass(a, "sc-cm__item_active")
        }
    }, b.MenuItem = function(a, c, d) {
        function e() {
            var a = "";
            return g.sandbox.Template.create("cmMenuItemTpl", g.menuItemTemplate), a = g.sandbox.Template.render("cmMenuItemTpl", {
                itemName: g.itemName,
                innerText: g.itemTitle,
                shortcutText: g.shortcutText,
                extraItemClass: g.extraClass
            }), i.create(a)[0]
        }
        function f(a) {
            var b = a,
                c = !0,
                d = g.getParentContextMenu();
            a.preventDefault(), g.disabledState || "function" != typeof g.onClick || (c = g.onClick(b)), c === !1 && d.hide()
        }
        var g = this,
            h = a.sandbox,
            i = h.UILib,
            j = null;
        this.parentElement = a, this.childElement = null, this.sandbox = this.parentElement.sandbox, this.menuTemplate = this.parentElement.menuTemplate, this.menuItemTemplate = this.parentElement.menuItemTemplate, this.menuSeparatorTemplate = this.parentElement.menuSeparatorTemplate, this.disabledState = d.disabled, this.itemName = c, this.itemTitle = d.itemTitle, this.extraClass = d.extraClass, this.shortcutText = a.shortcuts[c] ? a.shortcuts[c] : "", this.order = "number" == typeof d.order ? d.order : 0, this.group = d.group, this.focusable = "boolean" == typeof d.focusable ? d.focusable : !0, this.onClick = d.onClick, this.appendTo = function(a) {
            i.appendTo(j, a), this.attachEvents()
        }, this.destroy = function() {
            this.childElement && (this.childElement.destroy(), this.childElement = null), this.detachEvents(), i.remove(j)
        }, this.addItem = function(a, c) {
            this.childElement || (this.childElement = new b.Menu(this.sandbox, this.menuTemplate, this.menuItemTemplate, this.shortcutText, this.menuSeparatorTemplate, this.parentElement.shortcuts, j, null, "sc-cm_dropdown-menu"), this.childElement.parentElement = this, i.addClass(j, "sc-cm__item_dropdown sc-cm__item_arrow")), this.childElement.addItem(a, c)
        }, this.addItems = function(a) {
            for (var b in a) this.addItem(b, a[b])
        }, this.is = function(a) {
            return j === a
        }, this.attachEvents = function() {
            this.detachEvents(), g.sandbox.subscribe({
                eventType: "mousedown",
                element: j,
                handler: f
            })
        }, this.detachEvents = function() {
            g.sandbox.unsubscribe({
                eventType: "mousedown",
                element: j,
                handler: f
            })
        }, this.getDomElement = function() {
            return j
        }, this.setDisabled = function(a) {
            g.disabledState = a, i[a ? "addClass" : "removeClass"](j, "sc-cm__item_disabled")
        }, this.setActive = function() {
            a.removeActive(), i.addClass(j, "sc-cm__item_active")
        }, this.click = function() {
            h.fire({
                eventType: "mousedown",
                element: j
            })
        }, this.getParentContextMenu = function() {
            var a = this;
            do a = a.parentElement;
            while (a.parentElement);
            return a
        }, j = e(), this.setDisabled(this.disabledState)
    }, a.ContextMenu = b
}(SCAYT.UI, SCAYT.prototype), function(a, b) {
    "use strict";
    var c = (b.UILib, b.Utils),
        d = b.logger,
        e = "themes/",
        f = {},
        g = function(a) {
            this.basePath = a
        };
    g.prototype = {
        constructor: g,
        loadTheme: function(a, b) {
            if (a = a || "classic-blue", c.is(a, "String")) {
                var g = this.basePath + e + a + "/all.css",
                    h = null;
                b && "dev" === b && (g = "../../modules/ui/" + e + a + "/all.css"), "loaded" !== f[a] ? (f[a] = "loading", h = document.createElement("link"), h.id = a, h.setAttribute("rel", "stylesheet"), h.setAttribute("type", "text/css"), h.setAttribute("href", g), document.getElementsByTagName("head")[0].appendChild(h), h = void 0) : d.log({
                    name: "Load Theme",
                    msg: "Theme" + a + "not loading. Exists on the page"
                }), f[a] = "loaded"
            }
        }
    }, a.ThemeManager = g
}(SCAYT.UI || {}, SCAYT.prototype), function(a) {
    "use strict";
    var b = {
        htmlToText: function(a, b) {
            var c = "address|article|aside|blockquote|canvas|dd|div|dl|fieldset|figcaption|figure|footer|form|h[1-6]|header|hgroup|hr|li|main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video";
            return a = a.replace(new RegExp("<(" + c + ")(>|.*?[^?]>)", "gi"), '<br class="scayt-marker">$&').replace(new RegExp("</(" + c + ")(>|.*?[^?]>)", "gi"), '$&<br class="scayt-marker">').replace(/<br class="scayt-marker">\s*<br class="scayt-marker">/gi, '<br class="scayt-marker">').replace(/^(<br class="scayt-marker">)+/gi, "").replace(/(<br class="scayt-marker">)+$/gi, "").replace(/<br class="scayt-marker">/gi, "\r\n").replace(/<br>/gi, "\r\n").replace(/&nbsp;/g, " ").replace(/\ufeff/g, "").replace(/\u0002/g, ""), a = a.replace(/<br[^>]*class[^>]*=[^>]*"[^>]*scayt-bogus[^>]*"[^>]*>/g, ""), a = this.encodingTools.htmlDecode(a), b && (a = a.replace(/\r\n/g, " ")), a
        },
        textToHtml: function(a, b) {
            return a = a.replace(/</gi, "&lt;").replace(/>/gi, "&gt;").replace(/\r\n/g, "<br>").replace(/\n/gi, "<br>").replace(/\t/gi, "&nbsp;&nbsp;&nbsp;&nbsp;"), b && (a = a.replace(/ /g, "&nbsp;"), a = a.replace(/<br>/gi, "&nbsp;")), a
        },
        htmlToPlainText: function(a) {
            return this.encodingTools.htmlDecode(a)
        },
        tagsToLowerCase: function(a) {
            return a = a.replace(/<\/?[A-Z]+>/g, function(a) {
                return a.toLowerCase()
            })
        },
        getHtmlWithoutScaytNodes: function(a) {
            var a = this.getHtmlWithoutGivenNodes(a, "span", "scayt-misspell-word");
            return a
        },
        getHtmlWithoutGraytNodes: function(a) {
            var a = this.getHtmlWithoutGivenNodes(a, "span", "gramm-problem");
            return a
        },
        getHtmlWithoutRangyMarkerNodes: function(a) {
            var a = this.getHtmlWithoutGivenNodes(a, "span", "rangySelectionBoundary");
            return a = a.replace(/\ufeff/g, "")
        },
        getHtmlWithoutGivenNodes: function(b, c, d) {
            for (var e = 0, f = 0, g = b, h = !1, i = a.Utils, c = i.browser.ie && 8 === i.browser.version ? c.toUpperCase() : c; - 1 !== g.indexOf(d);) if (e = g.indexOf("<" + c, e), f = g.indexOf(">", e), h = e === g.lastIndexOf("<" + c) ? !0 : !1, g.indexOf(d, e) > f) {
                if (h) break;
                e = f
            } else {
                if (g = g.substring(0, e) + g.substring(f + 1, g.indexOf("</" + c + ">", f)) + g.substring(g.indexOf("</" + c + ">", f) + c.length + 3, g.length), h) break;
                e = 0, f = 0
            }
            return g
        },
        recogniseContentType: function(a) {
            var b = new RegExp("<[s]*[a-z0-9]+[s]*>|<[s]*/[s]*[a-z0-9]+[s]*>|<[s]*[a-z0-9]+[s]*/[s]*>", "gi");
            return a.match(b) ? "html" : "text"
        },
        encodingTools: function() {
            var a = {
                symbolsToSave: [{
                    searchFor: /\n/g,
                    replaceWith: "__%N%__"
                }, {
                    searchFor: /\r/g,
                    replaceWith: "__%R%__"
                }],
                symbolsToRestore: [{
                    searchFor: /__%N%__/g,
                    replaceWith: "\n"
                }, {
                    searchFor: /__%R%__/g,
                    replaceWith: "\r"
                }],
                save: function(a) {
                    a = a || "";
                    for (var b = 0; b < this.symbolsToSave.length; b++) a = a.replace(this.symbolsToSave[b].searchFor, this.symbolsToSave[b].replaceWith);
                    return a
                },
                restore: function(a) {
                    a = a || "";
                    for (var b = 0; b < this.symbolsToRestore.length; b++) a = a.replace(this.symbolsToRestore[b].searchFor, this.symbolsToRestore[b].replaceWith);
                    return a
                }
            };
            return {
                htmlEncode: function(b) {
                    var c, d, e;
                    return c = a.save(b), d = document.createElement("span"), e = document.createTextNode(c), d.appendChild(e), c = a.restore(d.innerHTML)
                },
                htmlDecode: function(b) {
                    var c, d = document.createElement("span");
                    return c = a.save(b), d.innerHTML = c, c = a.restore(d.textContent || d.innerText)
                }
            }
        }()
    };
    a.DataProcessor = b
}(SCAYT.prototype), function(a) {
    "use strict";

    function b(b, d, h, j) {
        function o(a) {
            var f, g = a,
                i = "",
                j = h ? "text" : k,
                l = null,
                o = b.Utils,
                s = o.getCurrentDocument(b.getOption("documentContainer")),
                w = b.getOption("isTextBasedContainer"),
                x = [];
            if (l = o.browser.edge ? o.getWindowByDocument(s).clipboardData : g && g.clipboardData, u || v) return a.preventDefault(), a.stopPropagation(), !1;
            if (p(), r && (q = b.saveSelection()), f = d.innerHTML, !l || !l.getData) return j = h ? "text" : "html", n.getPastedData(j, function(a) {
                b.fire({
                    eventType: "focus",
                    element: d
                }), b.restoreSelection(q), (!o.browser.ie || a) && setTimeout(function() {
                    b.fire("pasteProcessed", {
                        event: g,
                        text: a,
                        contentType: j,
                        pasteInto: d,
                        transferType: m.INTERNAL
                    })
                }, 0)
            }), !0;
            if (e(l.types)) for (var y = 0; y < l.types.length; y++) x[y] = l.types[y];
            t = !0, h && /text\/plain/.test(x) ? (j = "text", i = l.getData("text/plain")) : /text\/html/.test(x) ? (j = "html", i = l.getData("text/html")) : /text\/plain/.test(x) ? (j = "text", i = l.getData("text/plain")) : i = "", w && (i = i.replace(/&/gi, "&amp;")), d.innerHTML = i, c(d, f, function(a) {
                b.restoreSelection(q), (!o.browser.ie || a) && setTimeout(function() {
                    b.fire("pasteProcessed", {
                        event: g,
                        text: a,
                        contentType: j,
                        pasteInto: d,
                        transferType: m.INTERNAL
                    })
                }, 0)
            })
        }
        function p() {
            u = !0, setTimeout(function() {
                u = !1
            }, 100)
        } {
            var q, r = b.getFocused(),
                s = b.getOption("isIframe"),
                t = !1,
                u = !1,
                v = !1;
            a.Utils
        }
        b.subscribe({
            eventType: "focus",
            element: d,
            handler: function() {
                r = !0
            }
        }), b.subscribe({
            eventType: "blur",
            element: d,
            handler: function() {
                r = !1
            }
        }), b.subscribe({
            eventType: "cut",
            element: d,
            handler: function(a) {
                b.fire({
                    eventType: "cutProcessed",
                    data: a
                })
            }
        }), b.subscribe({
            eventType: "copy",
            element: d,
            handler: function(a) {
                b.fire({
                    eventType: "copyProcessed",
                    data: a
                })
            }
        }), b.subscribe({
            eventType: l,
            element: d,
            handler: o
        }), b.subscribe({
            eventType: "paste",
            element: d,
            handler: function(a) {
                return t ? (a.preventDefault(), a.stopPropagation(), !1) : void 0
            }
        }), b.subscribe("pasteProcessed", function(a) {
            {
                var b = a.pasteInto;
                f(a)
            }
            b == d && (a.contentTrueType = "html" == a.contentType ? "html" : i.recogniseContentType(a.text), "html" == a.contentTrueType && (a.text = i.tagsToLowerCase(a.text)), "text" == a.contentType && "html" == a.contentTrueType && (a.text = i.encodingTools.htmlEncode(a.text)), "auto" == a.contentType && (a.contentType = "html" == a.contentTrueType ? "html" : "text"))
        }, b, 2e3), b.subscribe("pasteProcessed", function(a) {
            var c = a.pasteInto;
            c == d && (v = !0, setTimeout(function() {
                var c, d, e, f, h = document.createElement("span");
                c = j && s ? b.getSelection(!0) : b.getSelection(), d = c.getRangeAt(0), h.innerHTML = a.text, d.deleteContents(), d.insertNode(h), e = b.createRange(), f = b.createRange(), e.selectNode(h), f.selectNodeContents(h), e.commonAncestorContainer().insertBefore(f.extractContents(), h), d.setStartBefore(h), d.collapse(!0), c.removeAllRanges(), c.addRange(d), v = !1, g.remove(h), b.fire("afterPaste")
            }, 0))
        }, b, -2e3)
    }
    function c(a, b, c) {
        var d = a.innerHTML;
        a.innerHTML = b, "function" == typeof c && c(d)
    }
    function d(a) {
        var b = a.container,
            c = a.sandbox;
        c.unsubscribe({
            eventType: "focus",
            element: b
        }), c.unsubscribe({
            eventType: "blur, cut, copy, paste, beforepaste",
            element: b
        }), c.unsubscribe("pasteProcessed", c)
    }
    function e(a) {
        return a && !a.propertyIsEnumerable("length") && "object" == typeof a && "number" == typeof a.length
    }
    function f(a) {
        return a.transferType = a.transferType || m.EXTERNAL, a.transferType
    }
    if (!a.clipboardManager) {
        var g = a.UILib,
            h = a.Utils,
            i = a.DataProcessor,
            j = [],
            k = "html",
            l = h.browser.ie ? "beforepaste" : "paste",
            m = {
                INTERNAL: 1,
                EXTERNAL: 2
            },
            n = {
                init: function(a) {
                    if (this.sandbox = a, !this.initialized) {
                        this.initialized = !0;
                        for (var b in this.contentTypes) this.contentTypes[b].element = g.create(this.contentTypes[b].template)[0], g.appendTo(this.contentTypes[b].element, "body")
                    }
                },
                getScrollTop: function() {
                    return g.scrollTop(window) + 10 + "px"
                },
                getScrollLeft: function() {
                    return g.scrollLeft(window) + "px"
                },
                contentTypes: {
                    text: {
                        template: '<textarea id="sc-hidden-paste-text-holder" style="position:absolute;left:-99999px;"></textarea>',
                        element: null,
                        cleanup: function() {
                            this.element.value = "", this.element.style.top = n.getScrollTop(), n.sandbox.fire({
                                eventType: "focus",
                                element: this.element
                            })
                        },
                        getData: function() {
                            return this.element.value
                        },
                        setData: function(a) {
                            this.element.value = a
                        }
                    },
                    html: {
                        template: '<div contenteditable="true" id="sc-hidden-paste-html-holder" style="position:absolute;left:-99999px;"></div>',
                        element: null,
                        cleanup: function() {
                            this.element.innerHTML = "", this.element.style.top = n.getScrollTop(), n.sandbox.fire({
                                eventType: "focus",
                                element: this.element
                            })
                        },
                        getData: function() {
                            return this.element.innerHTML
                        },
                        setData: function(a) {
                            this.element.innerHTML = a
                        }
                    }
                },
                getPastedData: function(a, b) {
                    var c = this;
                    b || (b = a, a = "html"), this.contentTypes[a].element && "function" == typeof b && (this.contentTypes[a].cleanup(), setTimeout(function() {
                        b(c.contentTypes[a].getData())
                    }, 0))
                }
            },
            o = {
                add: function(a, c, d, e) {
                    j.push({
                        sandbox: a,
                        container: c
                    }), n.init(a), b(a, c, d, e)
                },
                remove: function(a) {
                    for (var b, c = 0; c < j.length; c++) j[c].sandbox.getOption("uid") === a && (b = j[c], d(b), j.splice(c, 1))
                }
            };
        a.clipboardManager = o
    }
}(SCAYT.prototype), function(a, b) {
    "use strict";
    if (!a.UIMetrics) {
        var c = b.UILib,
            d = window,
            e = (document.documentElement, document.body, {});
        e.getScrollLeft = function() {
            return c.scrollLeft(d)
        }, e.getScrollTop = function() {
            return c.scrollTop(d)
        }, e.getWindowWidth = function() {
            return c.width(d)
        }, e.getWindowHeight = function() {
            return c.height(d)
        }, e.getWindowInnerWidth = function() {
            return "number" == typeof window.innerWidth ? window.innerWidth : document.documentElement.clientWidth
        }, e.getWindowInnerHeight = function() {
            return "number" == typeof window.innerHeight ? window.innerHeight : document.documentElement.clientHeight
        }, e.getBodyMinWidth = function() {
            var a = 0;
            return a = document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(document.body, null).minWidth : document.body.currentStyle ? document.body.currentStyle.minWidth : document.body.style.minWidth, parseInt(a, 10) || 0
        }, e.getPageWidth = function() {
            return Math.max(Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth), Math.max(document.body.offsetWidth, document.body.scrollWidth))
        }, e.getPageHeight = function() {
            return Math.max(Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight), Math.max(document.body.offsetHeight, document.body.scrollHeight))
        }, e.getDocumentWidth = function() {
            return Math.max(e.getPageWidth(), e.getBodyMinWidth(), e.getWindowWidth())
        }, e.getDocumentHeight = function() {
            return Math.max(e.getPageHeight(), e.getWindowHeight())
        }, a.UIMetrics = e
    }
}(SCAYT, SCAYT.prototype), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.UILib = b.UILib, this.Utils = b.Utils, this.DOM = b.DOM, this.control = b.getOption("container"), this.controlFocused = b.getOption("focused"), this.browser = this.Utils.browser, this.eventsNames = {
            focus: "focus",
            blur: "blur",
            beforefocus: "beforefocus",
            beforeblur: "beforemanualcontrolblur",
            restoreSelection: "restoreSelection"
        }, this.sandbox = b, this.bookmark = null
    };
    b.prototype = {
        constructor: b,
        init: function() {
            var a = this.sandbox,
                b = this.control;
            a.subscribe({
                eventType: this.eventsNames.focus,
                element: b,
                handler: this.focusHandler
            }), a.subscribe({
                eventType: this.eventsNames.restoreSelection,
                element: b,
                handler: this.restoreSelection
            }), a.subscribe({
                eventType: this.eventsNames.beforeblur,
                handler: this.beforeBlurHandler
            })
        },
        restoreSelection: function() {
            null !== this.bookmark && (this.sandbox.fire({
                eventType: "focus",
                element: this.control
            }), this.sandbox.restoreSelection(this.bookmark), this.bookmark = null)
        },
        focusHandler: function() {
            var a = this;
            setTimeout(function() {
                a.bookmark && a.sandbox.removeMarkers(a.bookmark)
            }, 0)
        },
        beforeBlurHandler: function() {
            this.bookmark = this.sandbox.saveSelection()
        }
    }, a.FocusManager = b
}(SCAYT), function(a) {
    "use strict";
    var b, c, d, e, f = a.prototype.UILib,
        g = a.prototype.Utils,
        h = a.prototype.DataProcessor,
        i = {
            internalDrop: 1,
            externalDrop: 2,
            crossContainerDrop: 3
        },
        j = 0,
        k = !1,
        l = function(a, b) {
            this.name = a, this.sandbox = b, this.container = this.sandbox.getOption("container"), this.isTextBasedContainer = this.sandbox.getOption("isTextBasedContainer")
        };
    l.prototype = {
        init: function() {
            var a = this;
            return g.browser.ie && g.browser.version <= 8 ? void this.sandbox.subscribe({
                eventType: "drop",
                element: this.container,
                handler: function(b) {
                    b.preventDefault(), a.sandbox.console.warn("Drag and Drop functionality are not supported in Internet Explorer 8 and its earlier versions.")
                }
            }) : (this.sandbox.subscribe({
                eventType: "drop",
                element: this.container,
                handler: a.handleNativeDrop
            }), this.sandbox.subscribe({
                eventType: "dragstart",
                element: this.container,
                handler: a.handleDragStart
            }), this.sandbox.subscribe({
                eventType: "dragend",
                element: this.container,
                handler: a.handleDragEnd
            }), void this.sandbox.subscribe("dropProcessed", function(b) {
                a.handleDrop(b)
            }, this, -2e3))
        },
        destroy: function() {
            this.removeAllEventHandlers()
        },
        handleNativeDrop: function(a) {
            var e, f, h, k, l, m, n = this.container;
            return e = this.isTextBasedContainer || g.browser.safari || g.browser.ie ? a.dataTransfer.getData("Text") || a.dataTransfer.getData("text/plain") : a.dataTransfer.getData("text/html"), !e && this.isTextBasedContainer ? void a.preventDefault() : (j = b ? b && d === n ? i.internalDrop : i.crossContainerDrop : i.externalDrop, f = this.getCaretRangeFromDrop(a), !f || this.isCaretRangeInEndOfDragRange(b, f) ? void a.preventDefault() : (b ? (h = this.isCaretRangeWillAffected(b, f), h || (c = this.sandbox.saveRange(b)), k = this.sandbox.saveRange(f), h && (c = this.sandbox.saveRange(b))) : k = this.sandbox.saveRange(f), l = j === i.internalDrop ? c : k, m = j === i.internalDrop ? k : null, void this.sandbox.fire("dropProcessed", {
                event: a,
                text: e,
                dropState: j,
                savedRange: l,
                savedRangeToRemove: m,
                savedCaretRange: k
            })))
        },
        handleDrop: function(a) {
            a.event.preventDefault(), k = !0, this.addContent(a.text, a.savedCaretRange)
        },
        handleDragStart: function() {
            b = this.sandbox.getSelection().getRangeAt(0), d = this.container
        },
        handleDragEnd: function(a) {
            {
                var d, e;
                this.sandbox.getOption("data_attribute_name")
            }(k || "none" !== a.dataTransfer.dropEffect) && (j === i.crossContainerDrop && this.sandbox.fire("crossContainerDrop", {
                event: a,
                savedRange: c
            }), d = k ? this.sandbox.restoreRange(c) : b, d && k && (e = this.sandbox.getSelection(), e.removeAllRanges(), e.addRange(d), g.browser.ie && this.sandbox.setOption("leftMouseButtonPressed", !1), this.sandbox.fire("removeMarkupInSelectionNode"), d = e.getRangeAt(0), d.deleteContents(), this.sandbox.fire("afterDrop"), this.sandbox.fire("startSpellCheck"), this.sandbox.fire("startGrammarCheck"))), this.clearTemporaryData()
        },
        addContent: function(a, b) {
            var c, d, e, i, j, k = this,
                l = this.sandbox.createRange(),
                m = this.sandbox.getOption("data_attribute_name"),
                n = document.createElement("span");
            a = h.getHtmlWithoutScaytNodes(a), a = h.getHtmlWithoutGraytNodes(a), a = a.replace(/<meta.*?>/i, ""), a = a.replace(/style="[^\"]*"/gi, ""), n.innerHTML = a, setTimeout(function() {
                k.sandbox.fire({
                    element: k.container,
                    eventType: "focus"
                }), j = k.sandbox.getSelection(), c = k.sandbox.restoreRange(b), d = c.startContainer(), g.browser.ie && k.sandbox.setOption("leftMouseButtonPressed", !1), g.browser.ie && k.sandbox.setOption("focused", !0), 0 === c.startOffset() && g.isEqualNode(d, m) ? (b = k.sandbox.saveRange(c), k.sandbox.fire("removeMarkupInSelectionNode", {
                    selectionNode: d
                }), c = k.sandbox.restoreRange(b)) : (j.removeAllRanges(), j.addRange(c), k.sandbox.fire("removeMarkupInSelectionNode"), c = j.getRangeAt(0)), c.insertNode(n), e = k.sandbox.createRange(), i = k.sandbox.createRange(), e.selectNode(n), i.selectNodeContents(n), e.commonAncestorContainer().insertBefore(i.extractContents(), n), l.setStartAfter(n), l.collapse(!0), j.removeAllRanges(), j.addRange(l), f.remove(n), k.clearTemporaryData(), k.sandbox.fire("afterDrop"), k.sandbox.fire("startSpellCheck"), k.sandbox.fire("startGrammarCheck")
            }, 50)
        },
        getCaretRangeFromDrop: function(a) {
            var b = this.sandbox.getSelection(),
                c = b.rangeCount() > 0 ? b.getRangeAt(0) : void 0;
            return this.sandbox.Utils.browser.ie && this.sandbox.Utils.browser.version > 8 && void 0 !== c && j === i.internalDrop ? c : this.sandbox.getCaretRangeFromEvent(a)
        },
        isCaretRangeWillAffected: function(a, b) {
            return a.endContainer() === b.startContainer() && a.endOffset() < b.endOffset() ? !0 : !1
        },
        isCaretRangeInEndOfDragRange: function(a, b) {
            return a && a.endContainer() === b.startContainer() && a.endOffset() === b.endOffset() ? !0 : !1
        },
        clearTemporaryData: function() {
            j = 0, b = null, c = null, d = null, e = null, k = !1
        },
        removeAllEventHandlers: function() {
            this.sandbox.unsubscribe({
                eventType: "drop, dragstart, dragend",
                element: this.container
            })
        }
    }, a.DragAndDropManager = l
}(SCAYT), function(a) {
    "use strict";
    a.prototype.UILib;
    a.ALT = .1, a.CTRL = .2, a.SHIFT = .4;
    var b = function(a, b) {
        this.name = a, this.sandbox = b, this.shortcutsList = {}
    };
    b.prototype = {
        init: function() {
            this.setShortcuts(this.sandbox.getOption("shortcutsList")), this.sandbox.subscribe({
                eventType: "keydown",
                element: this.sandbox.getOption("container"),
                handler: this.handleKeydown,
                priority: 1e3
            }), this.sandbox.subscribe("setShortcuts", function(a) {
                this.setShortcuts(a.shortcuts)
            }), this.sandbox.subscribe("removeShortcuts", function(a) {
                this.removeShortcuts(a.shortcuts)
            })
        },
        handleKeydown: function(b) {
            var c, d, e = b.keyCode || b.which;
            if ((b.ctrlKey || b.metaKey) && (e += a.CTRL), b.shiftKey && (e += a.SHIFT), b.altKey && (e += a.ALT), e = e.toFixed(1), this.shortcutsList.hasOwnProperty(e)) for (var f = 0, g = this.shortcutsList[e].length; g > f; f++) c = this.shortcutsList[e][f].callback, d = this.shortcutsList[e][f].context, c.call(d, b) || (b.preventDefault(), b.stopPropagation())
        },
        setShortcuts: function(a) {
            if (a.length) for (var b = 0, c = a.length; c > b; b++) this.setShortcut(a[b].shortcut, a[b].callback, a[b].context)
        },
        setShortcut: function(a, b, c) {
            a = a.toFixed(1), this.shortcutsList.hasOwnProperty(a) || (this.shortcutsList[a] = []), this.shortcutsList[a].push({
                callback: b,
                context: c || this
            })
        },
        removeShortcuts: function(a) {
            if (a.length) for (var b = 0, c = a.length; c > b; b++) this.removeShortcut(a[b].shortcut, a[b].callback)
        },
        removeShortcut: function(a, b) {
            a = a.toFixed(1);
            for (var c = 0, d = this.shortcutsList[a].length; d > c; c++) this.shortcutsList[a][c].callback === b && this.shortcutsList[a].splice(c, 1)
        }
    }, a.KeyboardManager = b
}(SCAYT), function(a) {
    "use strict";
    var b = (a.prototype.UILib, a.prototype.Utils),
        c = a.prototype.DataProcessor,
        d = function(a, b) {
            this.name = a, this.sandbox = b, this.data = [], this.container = this.sandbox.getOption("container"), this.limit = this.sandbox.getOption("undoDataSize") || 20, this.index = -1, this.isTyping = !1, this.isDeleted = !1, this.isDirty = !1
        };
    d.prototype = {
        init: function() {
            var a = this;
            this.sandbox.subscribe("allModulesReady", function() {
                this.setShortcuts()
            }), this.sandbox.subscribe({
                eventType: "keydown",
                element: this.container,
                handler: this.handleKeydown,
                priority: 1e3
            }), this.sandbox.subscribe({
                eventType: "click",
                element: this.container,
                handler: a.handleNavigation
            }), this.sandbox.subscribe("cutProcessed, replaceWord, replacePhrase", function() {
                this.handleCutReplace()
            }, this, 1e3), this.sandbox.subscribe("pasteProcessed", function(a) {
                this.handlePaste(a)
            }, this, -1e3), this.sandbox.subscribe("dropProcessed", function(a) {
                this.handleDrop(a)
            }, this, -1e3), this.sandbox.subscribe("crossContainerDrop", function(a) {
                this.handleCrossContainerDrop(a)
            }), this.sandbox.subscribe("executeUndo", function() {
                this.undo()
            }, this), this.sandbox.subscribe("executeRedo", function() {
                this.redo()
            }, this), this.sandbox.subscribe("checkUndoRedoPosibility", function() {
                this.checkUndoRedoPosibility()
            }, this), this.breakingRichMarkupCommands = {
                bold: !1,
                underline: !1,
                italic: !1
            }
        },
        destroy: function() {
            this.removeAllEventHandlers()
        },
        handleKeydown: function(a) {
            var b = a.keyCode || a.which,
                c = b >= 16 && 20 >= b || 91 === b || a.altKey || a.ctrlKey || a.metaKey,
                d = 13 === b || 8 === b || 46 === b;
            return b >= 33 && 40 >= b ? void this.handleNavigation() : (d || c || this.isTyping || (this.add({
                fixRichMarkup: !0
            }), this.isTyping = !0, this.isDeleted = !1, this.isDirty = !0), 13 === b && (this.add(), this.isTyping = !1, this.isDeleted = !1, this.isDirty = !0), void(8 !== b && 46 !== b || this.isDeleted || (this.add(), this.isTyping = !1, this.isDeleted = !0, this.isDirty = !0)))
        },
        setShortcuts: function() {
            var a = this;
            this.sandbox.fire("setShortcuts", {
                shortcuts: [{
                    shortcut: SCAYT.CTRL + 90,
                    callback: a.undo,
                    context: a
                }, {
                    shortcut: SCAYT.CTRL + SCAYT.SHIFT + 90,
                    callback: a.redo,
                    context: a
                }, {
                    shortcut: SCAYT.CTRL + 89,
                    callback: a.redo,
                    context: a
                }]
            }), this.sandbox.getOption("isTextBasedContainer") || this.sandbox.fire("setShortcuts", {
                shortcuts: [{
                    shortcut: SCAYT.CTRL + 66,
                    callback: function() {
                        a.execCommand("bold", !1, null), a.setBreakingRichMarkupCommands("bold")
                    },
                    context: a
                }, {
                    shortcut: SCAYT.CTRL + 73,
                    callback: function() {
                        a.execCommand("italic", !1, null), a.setBreakingRichMarkupCommands("italic")
                    },
                    context: a
                }, {
                    shortcut: SCAYT.CTRL + 85,
                    callback: function() {
                        a.execCommand("underline", !1, null), a.setBreakingRichMarkupCommands("underline")
                    },
                    context: a
                }]
            })
        },
        handlePaste: function(a) {
            (!a || a.text) && (this.add(), this.isDirty = !0)
        },
        handleCutReplace: function() {
            this.add(), this.isDirty = !0
        },
        handleDrop: function(a) {
            (!a || a.text) && (this.add(a), this.isDirty = !0)
        },
        handleCrossContainerDrop: function(a) {
            this.add(a), this.isDirty = !0
        },
        handleNavigation: function() {
            this.isTyping && (this.isTyping = !1), this.isDeleted && (this.isDeleted = !1), this.clearBreakingRichMarkupCommands()
        },
        add: function(a) {
            {
                var d, e, f, g;
                b.getCurrentDocument(this.sandbox.getOption("documentContainer"))
            }
            this.data.length && (d = this.sandbox.removeMarkupFromString(this.data[this.index].html), d = c.getHtmlWithoutRangyMarkerNodes(d)), e = this.sandbox.removeMarkupFromString(this.container.innerHTML), e = c.getHtmlWithoutRangyMarkerNodes(e), this.clearRedo(), (d !== e || a && a.savedRangeToRemove) && (a && a.savedRange || (f = this.sandbox.saveSelection(), g = this.sandbox.getSavedSelectionParentContainer(f)), this.checkDataLimit(), this.data.push({
                html: b.removeFillingCharacter(this.container.innerHTML),
                savedSelection: f ? f : null,
                savedRange: a && a.savedRange ? a.savedRange : null,
                savedRangeToRemove: a && a.savedRangeToRemove ? a.savedRangeToRemove : null
            }), f && (this.sandbox.restoreSelection(f), b.browser.gecko && g && g.normalize()), a && a.fixRichMarkup && this.fixRichMarkup(), this.clearBreakingRichMarkupCommands(), this.index = this.data.length - 1)
        },
        undo: function() {
            this.isDirty && (this.add(), this.clearFlags()), this.index <= 0 || (this.container.innerHTML = this.data[--this.index].html, this.restoreSelection(), this.clearFlags(), this.clearBreakingRichMarkupCommands(), this.sandbox.fire("undo", {
                undoLevel: this.data[this.index]
            }))
        },
        redo: function() {
            this.index >= this.data.length - 1 || (this.container.innerHTML = this.data[++this.index].html, this.restoreSelection(), this.clearFlags(), this.clearBreakingRichMarkupCommands(), this.sandbox.fire("redo", {
                undoLevel: this.data[this.index]
            }))
        },
        checkUndoRedoPosibility: function() {
            this.sandbox.fire("undoRedoPosibility", {
                canUndo: this.isDirty || this.index > 0 ? !0 : !1,
                canRedo: this.index < this.data.length - 1 ? !0 : !1
            })
        },
        clearRedo: function() {
            this.data.splice(this.index + 1)
        },
        clearFlags: function() {
            this.isTyping = !1, this.isDeleted = !1, this.isDirty = !1
        },
        checkDataLimit: function() {
            this.data.length > this.limit && this.data.shift()
        },
        restoreSelection: function() {
            var a, b = this.sandbox.getSelection(),
                c = this.data[this.index].savedSelection,
                d = this.data[this.index].savedRange,
                e = this.data[this.index].savedRangeToRemove;
            e && this.sandbox.restoreRange(e), c && (c.restored = !1, this.sandbox.restoreSelection(c)), d && (a = this.sandbox.restoreRange(d), b.removeAllRanges(), b.addRange(a))
        },
        removeAllEventHandlers: function() {
            this.sandbox.unsubscribe({
                eventType: "keydown",
                element: this.container,
                handler: this.handleKeydown
            }), this.sandbox.unsubscribe({
                element: this.container,
                eventType: "click",
                handler: this.handleNavigation
            })
        },
        setBreakingRichMarkupCommands: function(a) {
            a in this.breakingRichMarkupCommands && this.breakingRichMarkupCommands.hasOwnProperty(a) && (this.breakingRichMarkupCommands[a] = !this.breakingRichMarkupCommands[a])
        },
        clearBreakingRichMarkupCommands: function() {
            for (var a in this.breakingRichMarkupCommands) this.breakingRichMarkupCommands.hasOwnProperty(a) && (this.breakingRichMarkupCommands[a] = !1)
        },
        fixRichMarkup: function() {
            for (var a in this.breakingRichMarkupCommands) this.breakingRichMarkupCommands.hasOwnProperty(a) && this.breakingRichMarkupCommands[a] === !0 && this.execCommand(a, !1, null)
        },
        execCommand: function(a) {
            var c = b.getCurrentDocument(this.sandbox.getOption("documentContainer"));
            c.execCommand(a, !1, null)
        }
    }, a.UndoManager = d
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b
    };
    b.prototype = {
        init: function() {
            this.cache = this.createCacheSentences(), this.sandbox.subscribe("startGrammarCheck", function() {
                this.startGrammarCheck()
            }, this), this.sandbox.subscribe({
                eventType: "keydown",
                element: this.sandbox.getOption("container"),
                handler: function(a) {
                    var b = this.sandbox.getOption("graytState");
                    b && this.handleKeydown(a)
                }
            }), this.sandbox.subscribe("collectSentences", function(a) {
                var b = this.sandbox.getOption("graytState");
                b && this.findSentences(a.source)
            }, this), this.sandbox.subscribe("updateSentencesCache", function(a) {
                this.handleCacheUpdate(a)
            }, this), this.sandbox.subscribe("graytStateChanged", function(a) {
                a.state && this.sandbox.fire("updateSentencesCache", {
                    phrase: null
                })
            }, this)
        },
        handleCacheUpdate: function(a) {
            var b = a.phrase,
                c = a.phrasesInfo;
            b ? this.cache.deleteSentencesByPhrase(b) : c ? this.cache.update(c.sentence, c.phrases) : this.cache.clear()
        },
        createCacheSentences: function() {
            function a(c, d, e) {
                var f, g = b.sandbox.getOption("wordBoundaryRegex");
                if (e = e || 0, f = c.indexOf(d, e), f > 0) e = f + d.length, f = c.charAt(f - 1).match(g) ? f : "skipped", f = e === c.length || c.charAt(f + d.length).match(g) ? f : "skipped";
                else {
                    if (0 !== f) return !1;
                    e = f + d.length, f = c.charAt(f + d.length).match(g) ? f : "skipped"
                }
                return "skipped" == f ? a(c, d, e) : !0
            }
            var b = this,
                c = {},
                d = "sentence__";
            return {
                add: function(a) {
                    return c[d + a] = {
                        sentence: a,
                        phrases: []
                    }
                },
                get: function(a) {
                    return c[d + a]
                },
                deleteSentencesByPhrase: function(b) {
                    var d;
                    for (var e in c) d = c[e], a(d.sentence, b) && delete c[e]
                },
                update: function() {
                    var a = Object.prototype.toString.call(arguments[0]).slice(8, -1).toLowerCase(),
                        e = [];
                    if ("array" === a) {
                        for (var f = arguments[0], g = [], h = 0, i = (f.length, ""); i = f[h]; h++) if (c[d + i]) {
                            var j = c[d + i].phrases;
                            if (j && j.length > 0) {
                                var k = b.sandbox.getOption("lang");
                                g = g.concat(j)
                            }
                            c[d + i].stayAlive = !0
                        } else {
                            var l = this.add(i);
                            l.stayAlive = !0, e.push(i)
                        }
                        g = b.sandbox.Utils.arrayUnique(g, function(a, b) {
                            return a.phrase === b.phrase
                        }), b.sandbox.fireInAllApps("problemPhrasesFound", {
                            phrases: g,
                            lang: k
                        });
                        for (var m in c) c[m].stayAlive ? delete c[m].stayAlive : delete c[m];
                        return e
                    }
                    if ("string" === a) {
                        var i = arguments[0],
                            n = arguments[1] || [];
                        c[d + i] && (c[d + i].phrases = n)
                    }
                },
                isEmpty: function() {
                    return !!b.Utils.getKeys(c).length
                },
                clear: function() {
                    c = {}
                }
            }
        },
        findSentences: function(a) {
            var b, c, d = this;
            return this.sandbox.Utils.is(a, "String") && (b = this.collectSentencesFromString(a)), this.sandbox.Utils.is(a, "Object") && (b = this.collectSentencesInRange(a)), c = d.cache.update(b), this.sandbox.fire("sentencesCollected", {
                sentencesCollection: c
            }), c
        },
        collectSentencesInRange: function(a) {
            var b = this.createStringForGrammarCheck(a.commonAncestorContainer());
            return this.collectSentencesFromString(b)
        },
        createStringForGrammarCheck: function(a) {
            for (var b = this.sandbox.UILib, c = "", d = [a], e = d.shift(), f = this.sandbox.getOption("blockElementsRegex"), g = this.sandbox.getOption("ignoreElementsRegex"), h = this.sandbox.getOption("ignoreGraytElementsRegex"), i = new RegExp("(^|\\s)rangySelectionBoundary(\\s|$)"), j = /[.!?\n][\s\xA0]*$/g, k = /\S/; e;) {
                switch (e.nodeType) {
                    case 3:
                        c += e.nodeValue;
                        break;
                    case 1:
                        if (!i.test(b.attr(e, "className")) && !e.nodeName.match(g) && !e.nodeName.match(h)) {
                            for (var l = 0; l < e.childNodes.length; l++) d.splice(l, 0, e.childNodes[l]);
                            e.nodeName.match(f) && (d.length > e.childNodes.length && d.splice(l, 0, document.createTextNode("\n")), c.length > 0 && -1 === c.search(j) && -1 !== c.search(k) ? d.splice(0, 0, document.createTextNode("\n")) : c.length > 0 && " " != c[c.length - 1] && d.splice(0, 0, document.createTextNode(" ")))
                        }
                }
                e = d.shift()
            }
            return c = this.sandbox.Utils.replaceSpecialCharacters(c), c = this.sandbox.Utils.removeSpecialCharacters(c)
        },
        collectSentencesFromString: function(a) {
            function b(a) {
                function b(a) {
                    var b = /[\t|\v|\f|\r]+/g;
                    return b.lastIndex = 0, a.replace(b, " ")
                }
                function d(a, b, d) {
                    j = d.substring(a, b), j = c.sandbox.Utils.trim(j), j.length && g.push(j)
                }
                function e(a, b) {
                    this.position = a, this.offset = 5, this.left = b.substr(this.position - 5, 5), this.right = b.substr(this.position + 1, 6), this.toString = this.left.concat(b.charAt(this.position), this.right)
                }
                function f(a, b, c) {
                    if (10 === a.charCodeAt(0)) return d(h, b, c), void(h = i = b + 1);
                    var f = new e(b, c);
                    /\d/g.test(f.left) || /[\n|\t|\v|\f|\r]+/g.test(f.left) || /[A-ZА-Я]/g.test(f.left) || (/^[\s\xA0]+(?=[A-ZА-Я]{1})/g.test(f.right) && /[^A-ZА-Яа-яa-zЁё0-9_]/g.test(f.right) || !/\b/.test(f.right)) && (d(h, f.position + 1, c), h = i = f.position + 1)
                }
                var g = [],
                    h = 0,
                    i = 0,
                    j = "",
                    k = /[.!?\n](?=[\s\xA0]?)/gm;
                return k.lastIndex = 0, a = c.sandbox.Utils.trim(a), a = b(a), a.replace(k, f), d(i, a.length, a), g
            }
            var c = this;
            return a = a.source || a, b(a)
        },
        handleKeydown: function(a) {
            var b = this;
            (32 == a.keyCode || 13 == a.keyCode || 32 == a.charCode || 13 == a.charCode) && b.sandbox.addDeferredFunction("collectSentencesAfterKeypress", {
                single: !0,
                delay: 0,
                deferredFunction: function() {
                    b.startGrammarCheck()
                }
            }), b.sandbox.addDeferredFunction("collectSentencesAfter4Sec", {
                single: !0,
                delay: 4e3,
                deferredFunction: function() {
                    b.startGrammarCheck()
                }
            })
        },
        startGrammarCheck: function() {
            var a = this.sandbox.createRange(),
                b = this.sandbox.getOption("container");
            a.selectNodeContents(b), this.sandbox.fire("collectSentences", {
                source: a
            })
        }
    }, a.SentencesCollector = b
}(SCAYT), function(a) {
    "use strict";
    if (!a.GrammarDictionaryManager) {
        var b = function(a, b) {
            this.name = a, this.sandbox = b
        };
        b.prototype = {
            init: function() {
                this.sandbox.subscribe("sentencesCollected", function(a) {
                    this.sentencesCollectedHandler(a.sentencesCollection)
                }, this), this.sandbox.subscribe("getGrammarSuggestionsList", function(a) {
                    this.getSuggestionsListHandler(a.phrase, a.lang)
                }, this)
            },
            sentencesCollectedHandler: function(a) {
                var b = this.sandbox.getOption("lang");
                a.length > 0 && this.getPhraseInfo(a, b)
            },
            getSuggestionsListHandler: function(a, c) {
                this.sandbox.fire("suggestionListSend", {
                    suggestionList: b.Dictionary.getPhrase(a, c).suggestions
                })
            },
            getPhraseInfo: function(a, c) {
                var d = this,
                    e = b.Dictionary;
                this.sandbox.addDeferredFunction("getPhraseInfo", {
                    delay: 500,
                    collection: a,
                    partialItemsCount: 2,
                    deferredFunction: function(a) {
                        return d.sandbox.IO.get(new d.sandbox.IO.URL({
                            protocol: d.sandbox.getOption("service_protocol"),
                            host: d.sandbox.getOption("service_host"),
                            port: d.sandbox.getOption("service_port"),
                            path: d.sandbox.getOption("service_path")
                        }).addParameter("cmd", "grammar_check").addParameter("customerid", d.sandbox.getOption("customer_id")).addParameter("format", "json").addParameter("out_type", "words").addParameter("version", "1.0").addParameter("slang", c).addParameter("text", a.join(" ")), function(b) {
                            for (var f = [], g = 0; g < b.length; g++) f.push(e.addPhrase(b[g], c));
                            for (var g = 0; g < a.length; g++) d.sandbox.fire("updateSentencesCache", {
                                phrasesInfo: {
                                    sentence: a[g],
                                    phrases: f
                                }
                            });
                            d.sandbox.fireInAllApps("problemPhrasesFound", {
                                phrases: f,
                                lang: c
                            }), d.sandbox.setOption("numberOfFailedRequest", 0)
                        }, function() {
                            var b = d.sandbox.getOption("numberOfFailedRequest");
                            d.sandbox.setOption("numberOfFailedRequest", ++b), b > 4 ? (d.sandbox.setPaused(!0), d.sandbox.removeAllDeferredFunctions()) : d.getPhraseInfo(a, c)
                        }), !0
                    }
                })
            },
            getPhraseFromDictionary: function(a, c) {
                var d = b.Dictionary;
                return d.getPhrase(a, c)
            }
        }, b.Dictionary = b.Dictionary ||
            function() {
                var a = {},
                    b = {},
                    c = {},
                    d = "phrase_",
                    e = function(c, e) {
                        var f = c.phrase,
                            g = c.suggestions,
                            h = c.problem_id,
                            i = c.description;
                        return (!g || 0 === g.length || 1 === g.length && "" == g[0]) && (g = []), a[e] = a[e] || {}, a[e][d + f] = {
                            phrase: f,
                            suggestions: g,
                            problemId: h
                        }, ("string" == typeof h || "number" == typeof h) && (b[h] = i || ""), a[e][d + f]
                    };
                return {
                    addPhrase: function() {
                        return e.apply(this, arguments)
                    },
                    getPhrase: function(b, c) {
                        return a[c] && a[c][d + b]
                    },
                    getProblemDescription: function(a) {
                        return b[a]
                    },
                    each: function(c, d) {
                        if ("function" == typeof d) for (var e in a[c]) d(a[c][e], b[a[c][e].problemId])
                    },
                    clear: function() {
                        a = {}
                    },
                    setIgnoreInInstance: function(a, b) {
                        "undefined" != typeof b && (c[b] || (c[b] = {}), c[b][d + a] = !0)
                    },
                    isIgnoreInInstance: function(a, b) {
                        return "undefined" != typeof b ? c[b] && c[b][d + a] : void 0
                    }
                }
            }(), a.GrammarDictionaryManager = b
    }
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b
    };
    b.prototype = {
        init: function() {
            this.sandbox.subscribe("problemPhrasesFound", function(a) {
                this.processGrammarProblem(a.phrases, a.lang)
            }, this)
        },
        processGrammarProblem: function(b, c) {
            var d = this,
                e = d.sandbox.getOption("lang"),
                f = d.sandbox.getOption("uid"),
                g = a.GrammarDictionaryManager.Dictionary;
            if (c != e) return !1;
            for (var h = [], i = 0; i < b.length; i++) g.isIgnoreInInstance(b[i].phrase, f) || h.push(b[i].phrase);
            0 !== h.length && d.sandbox.addDeferredFunction("findGrammarProblemRangesForMarkup", {
                delay: 100,
                collection: h,
                partialItemsCount: 1,
                deferredFunction: function(a) {
                    {
                        var b, c, e = d.sandbox.getOption("focused"),
                            f = d.sandbox.getOption("documentContainer") === document.activeElement;
                        d.sandbox.Utils.getCurrentDocument(d.sandbox.getOption("documentContainer"))
                    }(e || f) && (b = d.sandbox.saveSelection(), c = d.sandbox.getSavedSelectionParentContainer(b));
                    var g = d.findPhraseRangesForMarkup(a);
                    d.sandbox.fire("markupPhrase", {
                        ranges: g
                    }), b && (d.sandbox.restoreSelection(b), d.sandbox.Utils.browser.gecko && c && c.normalize())
                }
            })
        },
        findPhraseRangesForMarkup: function(a) {
            var c, d = this.sandbox.createRange(),
                e = this.sandbox.getOption("container");
            d.selectNodeContents(e), c = new b.Finder(this.sandbox), c.collectBlockInfo(d.commonAncestorContainer());
            for (var f = [], g = 0; g < a.length; g++) if (a[g].length) for (c.lastIndex = 0; null !== c.findPhrase(a[g]);) f.push(c.phraseRange);
            return f.reverse()
        }
    }, b.Finder = function(a) {
        this.newParts = {
            getPos: function(a) {
                for (; !this[a];) a--;
                return this[a]
            }
        }, this.resultText = "", this.lastIndex = 0, this.phraseRange = null, this.reset = function() {
            this.resultText = "", this.lastIndex = 0, this.phraseRange = null;
            for (var a in this.newParts) this.newParts.hasOwnProperty(a) && "getPos" !== a && delete this.newParts[a]
        }, this.collectBlockInfo = function(b) {
            function c(a, b, c) {
                if (a !== b) {
                    var d = {
                        node: c.el,
                        start: j.resultText.length,
                        end: j.resultText.length + b - a,
                        offset: a
                    };
                    j.newParts[d.start] = d, j.newParts[d.end] = d, j.resultText += 0 == c.editable ? c.el.nodeValue.replace(/./g, " ").substring(a, b) : c.el.nodeValue.substring(a, b)
                }
            }
            for (var d, e = [{
                el: b,
                editable: "false" == b.getAttribute("contenteditable") ? !1 : !0
            }], f = e.shift(), g = a.getOption("lang"), h = a.getOption("languagesMap"), i = a.getOption("languageAttributeName"), j = (a.getOption("languageNodeName"), this), k = a.getOption("blockElementsRegex"), l = a.getOption("ignoreElementsRegex"), m = a.getOption("ignoreGraytElementsRegex"), n = a.getOption("problem_grammar_node"), o = a.getOption("problem_grammar_data_attribute"), p = new RegExp("(^|\\s)rangySelectionBoundary(\\s|$)"), q = /[.!?\n][\s\xA0]*$/g, r = /\S/, s = 0, t = "", u = [], v = a.getOption("specialCharactersRegex"); f;) {
                switch (f.el.nodeType) {
                    case 3:
                        f.el.length && (s = f.indexOffset || 0, t = f.el.nodeValue, u = t.substring(s).match(v), u ? (c(s, s + u.index, f), f.indexOffset = s + u.index + u[0].length, e.splice(0, 0, f)) : (c(s, t.length, f), f.emptyCharsCountInPart = 0));
                        break;
                    case 1:
                        if (d = f.el.lang && h[f.el.getAttribute(i)] !== g ? !0 : !1, f.el.nodeName.toLowerCase() == n.toLowerCase() && f.el.getAttribute(o)) this.resultText += f.el.getAttribute(o).replace(/./g, "_");
                        else if (!(p.test(a.UILib.attr(f.el, "className")) || l.test(f.el.nodeName) || m.test(f.el.nodeName) || d)) {
                            for (var w = "false" == f.el.getAttribute("contenteditable") ? !1 : !0, x = 0; x < f.el.childNodes.length; x++) e.splice(x, 0, {
                                el: f.el.childNodes[x],
                                editable: w
                            });
                            f.el.nodeName.match(k) && (e.length > f.el.childNodes.length && e.splice(x, 0, {
                                el: document.createTextNode("\n"),
                                editable: !0
                            }), this.resultText.length > 0 && -1 === this.resultText.search(q) && -1 !== this.resultText.search(r) ? e.splice(0, 0, {
                                el: document.createTextNode("\n"),
                                editable: !0
                            }) : this.resultText.length > 0 && " " != this.resultText[this.resultText.length - 1] && e.splice(0, 0, {
                                el: document.createTextNode(" "),
                                editable: !0
                            }))
                        }
                }
                f = e.shift()
            }
            this.resultText = a.Utils.replaceSpecialCharacters(this.resultText)
        }, this.findPhrase = function(b) {
            var c = this.resultText.indexOf(b, this.lastIndex),
                d = a.getOption("punctuationRegExp"),
                e = /.\s\xA0/,
                f = new RegExp("[" + e.source + d.source + "]", "g");
            if (c > 0) this.lastIndex = c + b.length, c = this.resultText.charAt(c - 1).match(f) ? c : "skipped", c = this.lastIndex === this.resultText.length || this.resultText.charAt(c + b.length).match(f) ? c : "skipped";
            else {
                if (0 !== c) return null;
                this.lastIndex = c + b.length, c = this.resultText.charAt(c + b.length).match(f) ? c : "skipped"
            }
            if ("skipped" == c) return this.findPhrase.call(this, b);
            var g = a.createRange(),
                h = this.newParts.getPos(c);
            g.setStart(h.node, c - h.start + h.offset);
            var i = this.newParts.getPos(c + b.length - 1);
            return g.setEnd(i.node, c + b.length - i.start + i.offset), g = a.Utils.fixRangeBoundaryPoints(g), this.phraseRange = g, this.phraseRange
        }
    }, a.GrammarPhrasesFinder = b
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.sandbox = b
    };
    b.prototype = {
        init: function() {
            this.sandbox.subscribe("replacePhrase", function(a) {
                this.replacePhraseInSelection(a.phrase, a.graytNode)
            }, this), this.sandbox.subscribe("ignorePhrase", function(a) {
                this.ignorePhraseInSelection(a.graytNode)
            }, this), this.sandbox.subscribe("ignoreAllPhrases", function(a) {
                this.ignorePhraseInDocument(a.graytNode)
            }, this)
        },
        replacePhraseInSelection: function(a, b) {
            var c;
            if (c = b ? b : this.sandbox.getGraytNodeFromSelection()) {
                var d = this.sandbox.UILib.attr(c, this.sandbox.getOption("problem_grammar_data_attribute"));
                this.sandbox.fire("updateSentencesCache", {
                    phrase: d
                }), this.replacePhraseByNode(c, a)
            }
        },
        ignorePhraseInSelection: function(a) {
            var b;
            b = a ? a : this.sandbox.getGraytNodeFromSelection(), b && this.ignorePhrases([b])
        },
        ignorePhraseInDocument: function(a) {
            var b, c = this.sandbox.getOption("container"),
                d = this.sandbox.getOption("problem_grammar_node"),
                e = this.sandbox.getOption("problem_grammar_data_attribute"),
                f = [];
            b = a ? a : this.sandbox.getGraytNodeFromSelection(), b && (f.push.apply(f, this.sandbox.DOM.query(c, d + "[" + e + '="' + b.getAttribute(e) + '"]')), this.ignorePhrases(f))
        },
        ignorePhrases: function(b) {
            for (var c = this.sandbox.saveSelection(), d = this.sandbox.createRange(), e = a.GrammarDictionaryManager.Dictionary, f = this.sandbox.getOption("problem_grammar_data_attribute"), g = this.sandbox.getOption("lang"), h = this.sandbox.getOption("uid"); b.length > 0;) {
                var i = b.shift(),
                    j = i.getAttribute(f);
                e.getPhrase(j, g) && e.setIgnoreInInstance(j, h), d.selectNode(i);
                var k = d.createContextualFragment(i.innerHTML);
                d.deleteContents(), d.insertNode(k), this.sandbox.fire("removedMarkupInContainer", {
                    ancestorContainer: d.commonAncestorContainer()
                })
            }
            this.sandbox.restoreSelection(c)
        },
        replacePhraseByNode: function(a, b) {
            a.innerHTML = b;
            var c = this.sandbox.createRange();
            c.selectNodeContents(a), c.collapse(!1);
            var d = this.sandbox.getSelection();
            d.removeAllRanges(), d.addRange(c);
            var e = this.sandbox.saveSelection();
            c = this.sandbox.createRange(), c.selectNode(a);
            var f = c.createContextualFragment(a.innerHTML);
            c.deleteContents(), c.insertNode(f), this.sandbox.fire("removedMarkupInContainer", {
                ancestorContainer: c.commonAncestorContainer()
            }), this.sandbox.restoreSelection(e)
        }
    }, a.SentencesProcessor = b
}(SCAYT), function(a) {
    "use strict";
    var b = function(a, b) {
        this.name = a, this.container = b.getOption("container"), this.sandbox = b
    };
    b.prototype = {
        init: function() {
            var a = this;
            this.sandbox.subscribe("markupPhrase", function(a) {
                this.markupPhrase(a.ranges)
            }, this), this.sandbox.subscribe({
                eventType: "keydown",
                element: this.container,
                handler: function(b) {
                    var c = this.sandbox.getOption("graytState");
                    c && a.handleKeydown(b)
                }
            }), this.sandbox.subscribe("removeMarkupInSelectionNode, removeGrammarMarkupInSelectionNode", function(a) {
                var b = this.sandbox.getOption("graytState");
                b && this.removeMarkupInSelectionNode(a)
            }, this), this.sandbox.subscribe("removeMarkupInDocument", function() {
                var a = this.sandbox.getOption("graytState");
                a && this.removeMarkupInDocument()
            }, this), this.sandbox.subscribe("removeMarkupFromPhrases", function(a) {
                this.removeMarkupFromPhrases(a.phrases)
            }, this), this.sandbox.subscribe("removeMarkup", function(a) {
                a.grayt && this.removeMarkup(a.nodes)
            }, this)
        },
        handleKeydown: function(a) {
            var b, c, d, e, f, g, h, i, j, k = this,
                l = this.sandbox.Utils,
                m = 67,
                n = 65,
                o = 90,
                p = 89,
                q = [45],
                r = [8, 13, 32, 106, 107, 109, 110, 111, 187, 186, 188, 190, 191, 192, 219, 220, 221, 222];
            r.push(l.browser.gecko ? 173 : 189), b = (a.ctrlKey || a.metaKey) && a.keyCode === m, c = (a.ctrlKey || a.metaKey) && a.keyCode === n, d = (a.ctrlKey || a.metaKey) && !a.shiftKey && a.keyCode === o, e = (a.ctrlKey || a.metaKey) && a.shiftKey && a.keyCode === o, f = (a.ctrlKey || a.metaKey) && !a.shiftKey && a.keyCode === p, g = !(b || c || d || e || f), h = a.keyCode > 40 && a.keyCode < 91 || a.keyCode >= 96 && a.keyCode <= 105, i = l.indexOf(q, a.keyCode) < 0, j = l.indexOf(r, a.keyCode) >= 0, (g && h && i || j) && k.removeMarkupInSelectionNode()
        },
        markupPhrase: function(a) {
            if (0 !== a.length) {
                var b = this,
                    c = b.sandbox.getOption("documentContainer"),
                    d = b.sandbox.getOption("problem_grammar_node"),
                    e = b.sandbox.getOption("problem_grammar_data_attribute"),
                    f = b.sandbox.getOption("problem_grammar_class"),
                    g = (b.sandbox.getOption("lang"), b.sandbox.Utils.getCurrentDocument(c).createElement(d));
                this.sandbox.UILib.addClass(g, f);
                for (var h = 0; h < a.length; h++) {
                    var i = a[h].commonAncestorContainer(),
                        j = b.sandbox.Utils.isEqualNode(i, e) ? [i] : b.sandbox.DOM.findNodeParents(i, d, e);
                    if (0 === j.length) {
                        var k = g.cloneNode(!0),
                            l = a[h].toString();
                        l = b.sandbox.Utils.removeSpecialCharacters(l), l = b.sandbox.Utils.replaceSpecialCharacters(l), k.setAttribute(e, l), k.appendChild(a[h].extractContents()), a[h].insertNode(k), this.sandbox.fire("markupedNode", {
                            node: k
                        });
                        for (var m = b.sandbox.DOM.findNodeChildren(k, d, e); m.length > 0;) {
                            var n = m.shift();
                            b.removeMarkup(n)
                        }
                    }
                }
            }
        },
        removeMarkupInDocument: function() {
            var a = this,
                b = this.container,
                c = a.sandbox.getOption("problem_grammar_node"),
                d = a.sandbox.getOption("problem_grammar_data_attribute"),
                e = a.sandbox.DOM.query(b, c + "[" + d + "]");
            a.removeMarkup(e), this.sandbox.fire("updateSentencesCache", {})
        },
        removeMarkupFromPhrases: function(a) {
            for (var b, c = this, d = this.sandbox.UILib, e = this.container, f = c.sandbox.getOption("problem_grammar_node"), g = c.sandbox.getOption("problem_grammar_data_attribute"), h = [], i = 0; i < a.length; i++) h.push.apply(h, c.sandbox.DOM.query(e, f + "[" + g + '="' + a[i].phrase + '"]'));
            c.removeMarkup(h), d.each(h, function(a, e) {
                b = d.attr(e, g), c.sandbox.fire("updateSentencesCache", {
                    phrase: b
                })
            })
        },
        removeMarkupInSelectionNode: function(a) {
            function b(a) {
                var b = [];
                return b = j.arrayFilter.call(a, function(a) {
                    return j.isEqualNode(a, l)
                }), 0 === b.length && (b = i.sandbox.DOM.findNodeParents(a[0], m, l)), b
            }
            var c, d, e, f, g, h, i = this,
                j = this.sandbox.Utils,
                k = this.sandbox.UILib,
                l = this.sandbox.getOption("problem_grammar_data_attribute"),
                m = this.sandbox.getOption("problem_grammar_node"),
                n = a && a.selectionNode,
                o = a && a.removeInside,
                p = a && a.forceBookmark,
                q = this.sandbox.getSelection(),
                r = this.container,
                s = [],
                t = [];
            n ? r.contains(n) && (e = i.sandbox.createRange(), e.selectNode(n), s = e.getNodes(), t = s) : q.rangeCount() > 0 && (e = q.getRangeAt(0), c = e.startContainer(), d = e.endContainer(), f = e.startOffset(), g = e.endOffset(), s = this.getNeighbourGraytNodes(c, d, f, g), t = e.getNodes(), t = s.concat(t), o && (s = t)), t = b(t), s = b(s), t = j.arrayUnique(t), s = j.arrayUnique(s);
            for (var u = 0, v = t.length; v > u; u += 1) h = k.attr(t[u], l), this.sandbox.fire("updateSentencesCache", {
                phrase: h
            });
            p && !this.sandbox.getOption("focused") && s.length > 0 && this.sandbox.fire({
                eventType: "focus",
                element: this.container
            });
            for (var u = 0, v = s.length; v > u; u += 1) s[u].innerHTML && i.removeMarkup(s[u])
        },
        getNeighbourGraytNodes: function(a, b, c, d) {
            function e(a, b, c) {
                var d, e, f, g = h.sandbox.getOption("container"),
                    k = /[^\t-\r \u0085\u00A0\u1680\u180E\u2000-\u200B\u2028\u2029\u202F\u205F\u3000]+/g,
                    n = h.sandbox.getOption("punctuationRegExp"),
                    o = h.sandbox.getOption("blockElementsRegex"),
                    p = /[^ \f\n\r\t\v\u00A0\u1680\u180E\u2000-\u200C\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
                if (b) {
                    f = new i.Walker(b, c, a, g);
                    do {
                        if (f.siblingNode && o.test(f.siblingNode.nodeName.toLowerCase()) && f.textWalkedThrough.length > 0 && p.test(f.textWalkedThrough)) break;
                        if (i.isEqualNode(f.currentNode, l) && f.textWalkedThrough.length > 0) {
                            d = f.currentNode;
                            break
                        }
                        if (e = i.removePunctuation(f.textWalkedThrough, n), a || (e = e.split("").reverse().join("")), k.lastIndex = 0, k.test(e) && k.lastIndex + 1 <= e.length) {
                            d = j.findNodeParents(f.currentNode, m, l)[0];
                            break
                        }
                    } while (f.getNext())
                }
                return d
            }
            var f, g, h = this,
                i = this.sandbox.Utils,
                j = (this.sandbox.UILib, this.sandbox.DOM),
                k = [],
                l = this.sandbox.getOption("problem_grammar_data_attribute"),
                m = this.sandbox.getOption("problem_grammar_node");
            return f = e(!1, a, c), g = e(!0, b, d), k = k.concat(f, g)
        },
        removeMarkup: function(a) {
            var b, c, d = (this.sandbox.Utils.getCurrentDocument(this.sandbox.getOption("documentContainer")), this.sandbox.getOption("focused")),
                e = [].concat(a);
            for (d && e.length > 0 && (b = this.sandbox.saveSelection(), c = this.sandbox.getSavedSelectionParentContainer(b)); e.length > 0;) {
                var f = e.shift(),
                    g = this.sandbox.createRange();
                g.selectNode(f);
                var h = g.createContextualFragment(f.innerHTML);
                g.deleteContents(), this.sandbox.fire("removedMarkupInContainer", {
                    node: g.commonAncestorContainer()
                }), g.insertNode(h)
            }
            this.sandbox.restoreSelection(b), this.sandbox.Utils.browser.gecko && c && c.normalize()
        }
    }, a.GrammarMarkup = b
}(SCAYT), SCAYT.CUSTOMSCAYT = function(a, b) {
    function c() {
        b && b.call(window)
    }
    function d() {
        return A.allModulesReady ? void B.fire("startSpellCheck", {}) : !1
    }
    function e() {
        return A.allModulesReady ? void B.fire("startGrammarCheck", {}) : !1
    }
    function f() {
        v(z), w.appState ? r(B) : s(B), "function" == typeof a.onLoad && a.onLoad.apply(H, arguments)
    }
    function g(a, b) {
        function c(b) {
            return defaultOptions[b].isValid(a[b]) ? a[b] : defaultOptions[b].defaultValue
        }
        var d = {},
            e = SCAYT.prototype.Utils,
            f = a.extraModules ? a.extraModules.replace(/\s/g, "").split(",") : [];
        defaultOptions = {
            autoStartup: {
                defaultValue: !1,
                type: "boolean",
                isValid: function(a) {
                    return "boolean" == typeof a
                }
            },
            contextMenuSections: {
                defaultValue: function() {
                    var a = "probleminfo|suggest|moresuggest|control|options";
                    return (e.inArray(f, "undo") || e.inArray(f, "clipboard")) && (a = "probleminfo|suggest|moresuggest|control|clipboard|options"), a
                }(),
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            contextMenuCommands: {
                defaultValue: function() {
                    var a = "problemdescription|ignoreall|addword|undo|redo|cut|copy|paste|settings|togglescayt";
                    return e.inArray(f, "undo") || (a = a.replace("undo|redo|", "")), e.inArray(f, "clipboard") || (a = a.replace("cut|copy|paste|", "")), a
                }(),
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            spellcheckLang: {
                defaultValue: "en_US",
                type: "string",
                isValid: function(a) {
                    return !!a
                }
            },
            suggestionsCount: {
                defaultValue: 3,
                type: "number",
                isValid: function(a) {
                    return "number" == typeof a && a >= 0
                }
            },
            moreSuggestionsCount: {
                defaultValue: 10,
                type: "number",
                isValid: function(a) {
                    return "number" == typeof a && a >= 0
                }
            },
            serviceProtocol: {
                defaultValue: null,
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            serviceHost: {
                defaultValue: null,
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            servicePort: {
                defaultValue: null,
                type: "number",
                isValid: function(a) {
                    return "string" == typeof a || "number" == typeof a
                }
            },
            servicePath: {
                defaultValue: null,
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            additionalMenuItems: {
                defaultValue: {},
                type: "object",
                isValid: function(a) {
                    return "object" == typeof a && !! a
                }
            },
            theme: {
                defaultValue: "classic-blue",
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a && !! SCAYT.CUSTOMSCAYT.options.supportedThemes[a]
                }
            },
            minWordLength: {
                defaultValue: 3,
                type: "number",
                isValid: function(a) {
                    return "number" == typeof a && a >= 1
                }
            },
            customDictionaryIds: {
                defaultValue: "",
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            userDictionaryName: {
                defaultValue: null,
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            uiTabs: {
                defaultValue: "options,languages,dictionaries,about",
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            extraModules: {
                defaultValue: "",
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            customerId: {
                defaultValue: "",
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a && !! a
                }
            },
            localization: {
                defaultValue: "en",
                type: "string",
                isValid: function(a) {
                    return "string" == typeof a
                }
            },
            shortcutsList: {
                defaultValue: [],
                type: "object",
                isValid: function(a) {
                    return "object" == typeof a && !! a
                }
            },
            undoDataSize: {
                defaultValue: 20,
                type: "number",
                isValid: function(a) {
                    return "number" == typeof a && a >= 1
                }
            },
            enableOnTouchDevices: {
                defaultValue: !1,
                type: "boolean",
                isValid: function(a) {
                    return "boolean" == typeof a
                }
            },
            contextMenuForMisspelledOnly: {
                defaultValue: !1,
                type: "boolean",
                isValid: function(a) {
                    return "boolean" == typeof a
                }
            },
            contextMenuByMouseover: {
                defaultValue: !1,
                type: "boolean",
                isValid: function(a) {
                    return "boolean" == typeof a
                }
            }
        };
        for (var g in defaultOptions) defaultOptions.hasOwnProperty(g) && (a[g] = c(g, defaultOptions[g].type, defaultOptions[g].defaultValue));
        if (a.contextMenuSections = a.contextMenuSections.replace(/\s/g, ""), a.contextMenuCommands = a.contextMenuCommands.replace(/\s/g, ""), e.inArray(f, "undo") || (a.contextMenuCommands = a.contextMenuCommands.replace(/undo\|?|redo\|?/g, "")), e.inArray(f, "clipboard") || (a.contextMenuCommands = a.contextMenuCommands.replace(/cut\|?|copy\|?|paste\|?/g, "")), a.customDictionaryIds = a.customDictionaryIds.replace(/\s/g, ""), a.uiTabs = a.uiTabs.replace(/\s/g, ""), a.uiTabs = a.uiTabs.split(","), a.extraModules = a.extraModules.replace(/\s/g, ""), a.extraModules = a.extraModules.split(","), d.basePath = b.basePath, d.localization = a.localization, d.lang = a.spellcheckLang, d.container = a.container, d.minWordLength = a.minWordLength, d.customDictionary = a.customDictionaryIds, d.userDictionaryName = a.userDictionaryName, d.customer_id = a.customerId, d.ignoreElementsRegex = a.elementsToIgnore, d.shortcutsList = a.shortcutsList, d.undoDataSize = a.undoDataSize, d.enableOnTouchDevices = a.enableOnTouchDevices, d.contextMenuForMisspelledOnly = a.contextMenuForMisspelledOnly, d.contextMenuByMouseover = a.contextMenuByMouseover, null !== a.serviceProtocol && (d.service_protocol = a.serviceProtocol), null !== a.serviceHost && (d.service_host = a.serviceHost), null !== a.servicePath && (d.service_path = a.servicePath), null !== a.servicePort && (d.service_port = a.servicePort), a.disableOptionsStorage && e.is(a.disableOptionsStorage, "Array")) {
            var h = a.disableOptionsStorage,
                i = ["all", "options", "lang", "ignore-all-caps-words", "ignore-domain-names", "ignore-words-with-mixed-cases", "ignore-words-with-numbers"],
                j = ["lang", "ignore-all-caps-words", "ignore-domain-names", "ignore-words-with-mixed-cases", "ignore-words-with-numbers"],
                k = e.inArray,
                l = e.indexOf,
                m = function(a) {
                    return !!k(i, a)
                },
                n = function(a) {
                    for (var b = [], c = 0; c < a.length; c++) {
                        var d = a[c],
                            e = !! k(a, "options");
                        if (!m(d) || e && -1 === l(j, "lang")) return;
                        if (k(j, d) && j.splice(l(j, d), 1), "all" === d || e && k(a, "lang")) return [];
                        "options" === d && (j = ["lang"])
                    }
                    return b = b.concat(j)
                };
            d["options-to-restore"] = n(h)
        }
        return "boolean" == typeof a.ignoreAllCapsWords && (d["ignore-all-caps-words"] = a.ignoreAllCapsWords), "boolean" == typeof a.ignoreDomainNames && (d["ignore-domain-names"] = a.ignoreDomainNames), "boolean" == typeof a.ignoreWordsWithMixedCases && (d["ignore-words-with-mixed-cases"] = a.ignoreWordsWithMixedCases), "boolean" == typeof a.ignoreWordsWithNumbers && (d["ignore-words-with-numbers"] = a.ignoreWordsWithNumbers), d
    }
    function h(a, b, c, f) {
        b.UILib, b.getOption("container");
        for (var g in a.additionalMenuItems)!
            function(c) {
                a.additionalMenuItems[c].onClick = function() {
                    var b = a.additionalMenuItems[c].onClick;
                    return function() {
                        var a = !0;
                        return "function" == typeof b && (a = b()), a
                    }
                }(b)
            }(g);
        b.subscribe("dialogDefinition", function(a) {
            var c, d = a.dialog,
                e = a.name;
            "pasteDialog" === e && (c = d.find(".sc-cm-paste-holder")[0], f.add(b, c, b.isOriginalContainerTextBased(), !0))
        }, c), b.subscribe({
            eventType: "cutProcessed",
            handler: function() {
                b.fire("removeMarkupInSelectionNode", {}), setTimeout(function() {
                    d(), e()
                }, 0)
            },
            context: c
        }), b.subscribe("pasteProcessed", function() {
            b.fire("removeMarkupInSelectionNode", {})
        }, c), b.subscribe("afterPaste", function() {
            d(), e()
        }, c), b.subscribe("suggestionListSend", function(a) {
            for (var b = {}, d = [], e = "word_", f = 0; f < a.suggestionList.length; f++) b[e + a.suggestionList[f]] || (b[e + a.suggestionList[f]] = a.suggestionList[f], d.push(a.suggestionList[f]));
            c.suggestions = d
        }, c), b.subscribe("beforeContextMenuShow", function(d) {
            var e, f, g = b.getSelection(),
                h = g.rangeCount() ? g.getRangeAt(0).collapsed() : !0;
            e = d.problemNode ? d.problemNode : b.getScaytNodeFromSelection(), e || (e = b.getGraytNodeFromSelection()), b.fire("checkUndoRedoPosibility"), f = j(a, b, e, h, c), c.contextMenu.addItems(f)
        }), b.subscribe("contextMenuHide", function() {
            B.fire("hideBanner", {})
        }, c), b.subscribe("undoRedoPosibility", function(a) {
            c.canUndo = a.canUndo, c.canRedo = a.canRedo
        }, c)
    }
    function i(a) {
        var b = a.contextMenuSections.split("|");
        if (b && b.length) for (var c = 0; c < b.length; c++) w.contextMenu.addGroup(b[c], c)
    }
    function j(a, b, c, d, e) {
        var f, g, h, i, j, m = {},
            n = {},
            o = b.UILib,
            p = a.contextMenuSections.split("|"),
            q = l(b, e, c),
            r = a.contextMenuCommands.split("|"),
            s = b.getOption("data_attribute_name"),
            t = b.getOption("problem_grammar_data_attribute"),
            u = b.getOption("lang"),
            v = {};
        f = b.Utils.isEqualNode(c, s), g = b.Utils.isEqualNode(c, t), f ? v = q.scayt : g && (v = q.grayt);
        for (var w in q.common) v[w] || (v[w] = q.common[w]);
        for (var w in a.additionalMenuItems) v[w] || (v[w] = a.additionalMenuItems[w]);
        if (r && r.length) for (var x = 0; x < r.length; x++) v[r[x]] && (n[r[x]] = v[r[x]], n[r[x]].order = x);
        for (var w in v) v[w].required && (b.Utils.indexOf(p, v[w].group) < 0 && e.contextMenu.addGroup(v[w].group), n[w] || (n[w] = v[w], n[w].order = ++x));
        c && (b.fire("showBanner", {
            contextMenuContainerSelector: e.contextMenu.getDOMElement()
        }), f ? b.fire("getSuggestionsList", {
            lang: b.getOption("lang"),
            word: o.attr(c, s)
        }) : g && (h = o.attr(c, t), i = SCAYT.GrammarDictionaryManager.Dictionary.getPhrase(h, u).problemId, j = SCAYT.GrammarDictionaryManager.Dictionary.getProblemDescription(i), v.problemdescription && j && (v.problemdescription.itemTitle = j), b.fire("getGrammarSuggestionsList", {
            lang: u,
            phrase: h
        })), m = k(b, e, c, f));
        for (var y in n)"function" == typeof n[y].isDisabled && (n[y].disabled = n[y].isDisabled(d)), "function" == typeof n[y].isVisible ? n[y].isVisible(c) && (m[y] = n[y]) : m[y] = n[y];
        return m
    }
    function k(b, c, d, e) {
        var f = {},
            g = c.suggestions,
            h = b.UILib,
            i = (b.getOption("container"), e ? "replaceWord" : "replacePhrase"),
            j = e ? "word" : "phrase",
            k = e ? "scaytNode" : "graytNode",
            l = e ? !0 : !1;
        return g && g.length > 0 ? h.each(g, function(e, g) {
            if (e < a.suggestionsCount) f["sugg_" + g.replace(/\s/g, "_")] = {
                itemTitle: g,
                order: e,
                group: "suggest",
                extraClass: "examples-variante",
                onClick: function() {
                    var a = {};
                    a[j] = g, a[k] = d, b.fire("restoreSelection"), b.fire(i, a), l && b.fire("removeGrammarMarkupInSelectionNode")
                }
            };
            else if (e < a.suggestionsCount + a.moreSuggestionsCount) {
                var h = c.contextMenu.getItem("moresuggestions");
                h || c.contextMenu.addItem("moresuggestions", {
                    itemTitle: b.getLocal("btn_moreSuggestions", b),
                    order: 0,
                    group: "moresuggest",
                    onClick: function() {
                        return !0
                    }
                }), h = c.contextMenu.getItem("moresuggestions"), h && h.addItem("sugg_" + g.replace(/\s/g, "_"), {
                    itemTitle: g,
                    onClick: function() {
                        var a = {};
                        a[j] = g, a[k] = d, b.fire("restoreSelection"), b.fire(i, a), l && b.fire("removeGrammarMarkupInSelectionNode")
                    }
                })
            }
        }) : f.nosuggestions = {
            itemTitle: b.getLocal("btn_noSuggestions", b),
            order: 0,
            group: "suggest",
            disabled: !0
        }, f
    }
    function l(a, b, c) {
        function d(b) {
            function c() {
                alert(b), a.fire("restoreSelection")
            }
            a.Utils.browser.gecko ? setTimeout(c, 10) : c()
        } {
            var e = a.UILib;
            a.getOption("container"), a.getOption("contextMenuByMouseover")
        }
        return {
            scayt: {
                ignore: {
                    itemTitle: a.getLocal("btn_ignore", a),
                    order: 0,
                    group: "control",
                    isVisible: function(a) {
                        return !!a && b.appState
                    },
                    onClick: function() {
                        a.fire("restoreSelection"), a.fire("ignoreWord", {
                            scaytNode: c
                        })
                    }
                },
                ignoreall: {
                    itemTitle: a.getLocal("btn_ignoreAll", a),
                    order: 1,
                    group: "control",
                    isVisible: function(a) {
                        return !!a && b.appState
                    },
                    onClick: function() {
                        a.fire("restoreSelection"), a.fire("ignoreAllWords", {
                            scaytNode: c
                        })
                    }
                },
                addword: {
                    itemTitle: a.getLocal("btn_addWord", a),
                    order: 2,
                    group: "control",
                    isVisible: function(a) {
                        return !!a && b.appState
                    },
                    onClick: function() {
                        a.fire("restoreSelection"), setTimeout(function() {
                            a.fire("addWordToUserDictionary", {
                                scaytNode: c
                            })
                        }, 10)
                    }
                }
            },
            grayt: {
                problemdescription: {
                    itemTitle: "Grammar problem description",
                    order: 0,
                    group: "probleminfo",
                    disabled: !0,
                    onClick: function(a) {
                        e.preventDefault(a)
                    }
                },
                ignore: {
                    itemTitle: a.getLocal("btn_ignore", a),
                    order: 0,
                    group: "control",
                    isVisible: function(a) {
                        return !!a && b.appState
                    },
                    onClick: function() {
                        a.fire("restoreSelection"), a.fire("ignorePhrase", {
                            graytNode: c
                        })
                    }
                },
                ignoreall: {
                    itemTitle: a.getLocal("btn_ignoreAll", a),
                    order: 1,
                    group: "control",
                    isVisible: function(a) {
                        return !!a && b.appState
                    },
                    onClick: function() {
                        a.fire("restoreSelection"), a.fire("ignoreAllPhrases", {
                            graytNode: c
                        })
                    }
                }
            },
            common: {
                undo: {
                    itemTitle: a.getLocal("btn_undo", a),
                    order: 0,
                    group: "clipboard",
                    extraClass: "clipboard-action",
                    isDisabled: function() {
                        return !b.canUndo
                    },
                    onClick: function() {
                        a.fire("restoreSelection"), a.fire("executeUndo", {})
                    }
                },
                redo: {
                    itemTitle: a.getLocal("btn_redo", a),
                    order: 1,
                    group: "clipboard",
                    extraClass: "clipboard-action",
                    isDisabled: function() {
                        return !b.canRedo
                    },
                    onClick: function() {
                        a.fire("restoreSelection"), a.fire("executeRedo", {})
                    }
                },
                copy: {
                    itemTitle: a.getLocal("btn_copy", a),
                    order: 2,
                    group: "clipboard",
                    extraClass: "clipboard-action",
                    isDisabled: function(a) {
                        return a
                    },
                    onClick: function() {
                        d(a.getLocal("message_info_copy", a))
                    }
                },
                paste: {
                    itemTitle: a.getLocal("btn_paste", a),
                    order: 3,
                    group: "clipboard",
                    extraClass: "clipboard-action",
                    onClick: function() {
                        return b.openDialog("pasteDialog"), !1
                    }
                },
                cut: {
                    itemTitle: a.getLocal("btn_cut", a),
                    order: 4,
                    group: "clipboard",
                    extraClass: "clipboard-action",
                    isDisabled: function(a) {
                        return a
                    },
                    onClick: function() {
                        d(a.getLocal("message_info_cut", a))
                    }
                },
                settings: {
                    itemTitle: a.getLocal("btn_settings", a),
                    order: 0,
                    group: "options",
                    isDisabled: function() {
                        return !b.appState
                    },
                    onClick: function() {
                        return this.sandbox.Utils.browser.chrome && this.sandbox.getSelection().removeAllRanges(), b.openDialog("scaytDialog").setActiveTab(a.scaytOptions.uiTabs[0]), !1
                    }
                },
                togglescayt: {
                    itemTitle: b.appState ? a.getLocal("btn_disable", a) : a.getLocal("btn_enable", a),
                    order: 1,
                    group: "options",
                    onClick: function() {
                        a.fire("restoreSelection"), b.appState = !b.appState, b.appState ? r(a) : s(a)
                    }
                },
                help: {
                    itemTitle: a.getLocal("btn_help", a),
                    order: 2,
                    group: "options",
                    onClick: function() {
                        a.fire("restoreSelection"), window.open(a.getOption("scaytSupportUrl"), "_blank")
                    }
                }
            }
        }
    }
    function m(a) {
        function b(a) {
            var b, c;
            b = d.createStyleSheet(a), c = b.ownerNode ? b.ownerNode : b.owningElement
        }
        var c;
        if (a.getOption("basePath")) {
            for (var d = "iframe" == a.getOption("documentContainer").nodeName.toLowerCase() ? a.getOption("documentContainer").contentWindow.document : document, e = d.getElementsByTagName("link"), f = 0; f < e.length; f++) if (e[f].href == a.getOption("cssPath")) return;
            document.createStyleSheet ? "complete" == d.readyState ? b(a.getOption("cssPath")) : d.onreadystatechange = function() {
                "complete" == d.readyState && b(a.getOption("cssPath"))
            } : (c = document.createElement("link"), c.setAttribute("rel", "stylesheet"), c.setAttribute("type", "text/css"), c.setAttribute("href", a.getOption("cssPath")), d.getElementsByTagName("head")[0].appendChild(c))
        }
    }
    function n(a) {
        var b = a.Utils,
            c = a.UILib;
        b.browser.ie && (c.addClass("html", "ie" + b.browser.version), b.browser.version < 9 && c.addClass("html", "lt-ie9")), ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch) && (c.addClass("html", "touch"), a.setOption("isTouchDevice", !0))
    }
    function o(a, b) {
        var c = a.UILib;
        c.attr(b, "aria-readonly", !1), c.attr(b, "spellcheck", !1)
    }
    function p(a, b) {
        for (var c = {
            ui: function() {
                a.FocusManager = SCAYT.FocusManager, a.ContextMenu = SCAYT.UI.ContextMenu
            },
            dnd: function() {
                a.DragAndDropManager = SCAYT.DragAndDropManager
            },
            undo: function() {
                a.UndoManager = SCAYT.UndoManager
            }
        }, d = 0; d < b.length; d++) c.hasOwnProperty(b[d]) && c[b[d]]()
    }
    function q() {
        var a, b, c = B.getSelection();
        if (c.rangeCount() > 0 && (a = c.getRangeAt(0), b = a.toString(), !b && 0 === a.getNodes().length)) try {
            c.expand("word"), B.fire("selectionIsChanged", {})
        } catch (d) {}
    }
    function r(a) {
        t(a, !1), a.getOption("graytState") && u(a, !1), a.fire("startSpellCheck"), a.fire("startGrammarCheck"), w.appState = !0
    }
    function s(a) {
        a.fire("removeMarkupInDocument", {}), t(a, !0), u(a, !0), a.removeAllDeferredFunctions(), w.appState = !1
    }
    function t(a, b) {
        var c = ["startSpellCheck", "markupWords", "removeMarkupInDocument", "removeMarkupFromWords", "removeMarkupInSelectionNode", "replaceWord", "ignoreWord", "ignoreAllWords", "collectWords", "wordsCollected", "misspelledWordsFound"];
        a[b ? "blockEvents" : "unblockEvents"](c)
    }
    function u(a, b) {
        var c = ["startGrammarCheck", "markupPhrase", "removeMarkupFromPhrases", "removeGrammarMarkupInSelectionNode", "replacePhrase", "ignorePhrase", "ignoreAllPhrases", "sentencesCollected", "getGrammarSuggestionsList", "problemPhrasesFound", "collectSentences"];
        a[b ? "blockEvents" : "unblockEvents"](c)
    }
    function v(a) {
        var b = B.getOption("graytLangList"),
            c = B.getOption("lang");
        !a || c in b.ltr || c in b.rtl || (a = !1), B.setOption("graytState", a), B.fire("graytStateChanged", {
            state: a
        }), u(B, !a)
    }
    var w = this,
        x = SCAYT.prototype.Utils;
    this._ = {};
    var y = g(a, this),
        z = a.enableGrayt;
    delete a.enableGrayt;
    var A = new SCAYT(y),
        B = new SCAYT.Sandbox("CUSTOMSCAYTApp", A);
    B.scaytOptions = a, this.appState = a.autoStartup, m(B), A.instanceManager.add(B), x.inArray(a.extraModules, "ui") && n(B);
    var C = '<div id="scayt_banner"><div class="img-banner"><img src="' + w.basePath + 'css/webspellchecker-logo-small.png"><span>WebSpellChecker</span></div><ul class="more-list"><li>No banner</li><li>More languages</li><li>Technical support</li><li>Extra features</li></ul><div class="button-holder"><a target="_blank" href="http://www.webspellchecker.net/signup/froala-scayt-signup.html" class="sc-upgrade">Upgrade Now</a></div>';
    B.setOption("bannerTemplate", C), B.setOption("bannerType", "scayt");
    var D = {
        IME: SCAYT.IME,
        Banner: SCAYT.Banner,
        WordsCollector: SCAYT.WordsCollector,
        WordsFinder: SCAYT.WordsFinder,
        Dictionary: SCAYT.DictionaryManager,
        Markup: SCAYT.Markup,
        WordsProcessor: SCAYT.WordsProcessor,
        KeyboardManager: SCAYT.KeyboardManager,
        SentencesCollector: SCAYT.SentencesCollector,
        SentencesDictionary: SCAYT.GrammarDictionaryManager,
        GrammarPhrasesFinder: SCAYT.GrammarPhrasesFinder,
        SentencesProcessor: SCAYT.SentencesProcessor,
        GrammarMarkup: SCAYT.GrammarMarkup
    };
    p(D, a.extraModules), B.subscribe("allModulesReady", f), B.subscribe("allModulesReady", c), A.initModules(D), x.inArray(a.extraModules, "ui") && (this.contextMenu = A.getService("ContextMenu"), this.ThemeManager.loadTheme(a.theme, SCAYT.environment), h(a, B, this, A.clipboardManager), i(a, this)), x.inArray(a.extraModules, "clipboard") && A.clipboardManager.add(B, B.getOption("container"), B.isOriginalContainerTextBased()), x.inArray(a.extraModules, "undo") && (this.canUndo = !1, this.canRedo = !1);
    var E = B.getOption("container");
    o(B, E), B.subscribe({
        eventType: "dblclick",
        element: E,
        handler: q
    }), B.subscribe("commitOptions", function(a) {
        if (!B.Utils.objectIsEmpty(a)) {
            a.lang && a.lang !== B.getOption("lang") && (B.fire("removeMarkupInDocument", {}), B.removeAllDeferredFunctions()), B.setPaused(!0);
            var b = SCAYT.DictionaryManager.Dictionary,
                c = B.getOption("lang");
            b.each(c, function(a) {
                a.getStatus(B.getOption("uid")) == SCAYT.DictionaryManager.wordStatus.inprocess && a.setStatus(SCAYT.DictionaryManager.wordStatus.unknown, B.getOption("uid"))
            });
            for (var f in a) a.hasOwnProperty(f) && B.setOption(f, a[f]);
            B.setPaused(!1), v(z), d(), e()
        }
    }, w), B.Localization.loadLocalization(B.getOption("localization"), B), B.fire("appStarted", {
        document: B.getOption("container")
    }), B.getLocal = function(a) {
        return B.Localization.getLocal(a, B.getOption("localization"))
    }, this.openDialog = function(a, b) {
        var c = SCAYT.UI.Dialog._.dialogDefinitions[a],
            d = this._.storedDialogs || (this._.storedDialogs = {}),
            e = null;
        return "function" == typeof c && (e = d[a] || (d[a] = new SCAYT.UI.Dialog(B, a)), "function" == typeof b && b.call(e, e), e.show()), e
    };
    var F = A.getService("Dictionary"),
        G = A.getService("SentencesDictionary"),
        H = {
            reloadMarkup: function() {
                d(), e()
            },
            replaceSelectionNode: function(a) {
                var b = a && a.word ? "replaceWord" : "replacePhrase";
                B.fire(b, a)
            },
            getSuggestions: function(a) {
                var b = a && a.word ? F.getWordFromDictionary(a.word, a.lang) : G.getPhraseFromDictionary(a.phrase, a.lang),
                    c = b && b.suggestions ? b.suggestions : null;
                return c
            },
            ignoreWord: function() {
                B.fire("ignoreWord")
            },
            ignorePhrase: function() {
                B.fire("ignorePhrase")
            },
            addWordToUserDictionary: function(a, b, c) {
                B.fire("addWordToUserDictionary", {
                    word: a,
                    onSuccess: b,
                    onError: c
                })
            },
            deleteWordFromUserDictionary: function(a, b, c) {
                B.fire("deleteWordFromUserDictionary", {
                    word: a,
                    onSuccess: b,
                    onError: c
                })
            },
            ignoreAllWords: function() {
                B.fire("ignoreAllWords")
            },
            removeMarkupInSelectionNode: function(a) {
                var b = a && a.grammarOnly ? "removeGrammarMarkupInSelectionNode" : "removeMarkupInSelectionNode";
                B.fire(b, a)
            },
            destroy: function() {
                var b = B.Utils;
                B.getOption("paused") && B.setPaused(!1), B.fire("removeMarkupInDocument", {}), b.inArray(a.extraModules, "clipbord") && A.clipboardManager.remove(B.getOption("uid")), A.instanceManager.remove(B.getOption("uid")), B.unsubscribe({
                    eventType: "dblclick",
                    element: E,
                    handler: q
                }), A.destroyModules(), B.setPaused(!0);
                for (var c in this) this.hasOwnProperty(c) && delete this[c]
            },
            getScaytLangList: function() {
                return B.getOption("scaytLangList")
            },
            getGraytLangList: function() {
                return B.getOption("graytLangList")
            },
            getApplicationConfig: function() {
                return B.getOption(["ignore-all-caps-words", "ignore-domain-names", "ignore-words-with-mixed-cases", "ignore-words-with-numbers"])
            },
            getLang: function() {
                return B.getOption("lang")
            },
            setLang: function(a) {
                B.fire("commitOptions", {
                    lang: a
                })
            },
            commitOption: function(a) {
                B.fire("commitOptions", a)
            },
            getOption: function(a) {
                return B.getOption(a)
            },
            getUserDictionaryName: function() {
                return B.getOption("userDictionaryName")
            },
            createUserDictionary: function(a, b, c) {
                B.fire("createUserDictionary", {
                    name: a,
                    onSuccess: b,
                    onError: c
                })
            },
            restoreUserDictionary: function(a, b, c) {
                B.fire("restoreUserDictionary", {
                    name: a,
                    onSuccess: b,
                    onError: c
                })
            },
            disconnectFromUserDictionary: function(a, b, c) {
                B.fire("disconnectFromUserDictionary", {
                    name: a,
                    onSuccess: b,
                    onError: c
                })
            },
            renameUserDictionary: function(a, b, c) {
                B.fire("renameUserDictionary", {
                    newName: a,
                    onSuccess: b,
                    onError: c
                })
            },
            removeUserDictionary: function(a, b, c) {
                B.fire("removeUserDictionary", {
                    name: a,
                    onSuccess: b,
                    onError: c
                })
            },
            setUserDictionaryName: function(a) {
                B.fire("setUserDictionaryName", {
                    name: a
                })
            },
            isUserDictionaryExist: function() {
                return "string" == typeof B.getOption("userDictionaryName")
            },
            removeMarkupFromString: function(a) {
                return B.removeMarkupFromString(a)
            },
            getLogo: function() {
                return B.getOption("basePath") + B.getOption("scaytLogo")
            },
            getVersion: function() {
                return B.getOption("scaytVersion")
            },
            isScaytNode: function(a) {
                var b = B.getOption("data_attribute_name");
                return B.Utils.isEqualNode(a, b)
            },
            isGraytNode: function(a) {
                var b = B.getOption("problem_grammar_data_attribute");
                return B.Utils.isEqualNode(a, b)
            },
            findScaytNode: function(a) {
                for (var b = 0; b < a.length; b++) if (this.isScaytNode(a[b])) return a[b];
                return null
            },
            findGraytNode: function(a) {
                for (var b = 0; b < a.length; b++) if (this.isGraytNode(a[b])) return a[b];
                return null
            },
            getProblemNodeFromSelection: function() {
                var a;
                return a = B.getScaytNodeFromSelection(), a || (a = B.getGraytNodeFromSelection()), a
            },
            setCustomDictionary: function(a) {
                B.setOption("customDictionary", a)
            },
            setUserDictionary: function(a) {
                B.setOption("userDictionaryName", a)
            },
            getScaytNodeAttributeName: function() {
                return B.getOption("data_attribute_name")
            },
            getGraytNodeAttributeName: function() {
                return B.getOption("problem_grammar_data_attribute")
            },
            getContainerNode: function() {
                return B.getOption("container")
            },
            getCustomDictionary: function() {
                return B.getOption("customDictionary")
            },
            getLocal: function(a) {
                return B.Localization.getLocal(a, B.getOption("localization"))
            },
            isDisabled: function() {
                return !w.appState
            },
            setDisabled: function(a) {
                w.appState === a && (a ? s(B) : r(B))
            },
            getProblemsCount: function() {
                for (var a = B.getScaytNodesInElement(), b = B.getGraytNodesInElement(), c = a.concat(b), d = 0, e = 0, f = c.length; f > e; e++) c[e].innerHTML && d++;
                return d
            },
            fixProblemNodesInElement: function(a) {
                var b = B.getBrokenScaytNodes(a),
                    c = B.getBrokenGraytNodes(a);
                b && (B.fire("removeMarkup", {
                    nodes: b,
                    scayt: !0
                }), this.reloadMarkup()), c && (B.fire("removeMarkup", {
                    nodes: c,
                    grayt: !0
                }), this.reloadMarkup())
            }
        };
    return H
}, SCAYT.CUSTOMSCAYT.prototype.basePath = function() {
    var a = window.SCAYT_BASEPATH || "";
    if (!a) for (var b = document.getElementsByTagName("script"), c = 0; c < b.length; c++) {
        var d = b[c].src.match(/(^|.*[\\\/])customscayt.js(?:\?.*)?$/i);
        if (d) {
            a = d[1];
            break
        }
    }
    if (-1 == a.indexOf(":/") && (a = 0 === a.indexOf("/") ? window.location.href.match(/^.*?:\/\/[^\/]*/)[0] + a : window.location.href.match(/^[^\?]*\/(?:)/)[0] + a), !a) throw "Path could not be automatically detected.";
    return a
}(), SCAYT.CUSTOMSCAYT.prototype.ThemeManager = new SCAYT.UI.ThemeManager(SCAYT.CUSTOMSCAYT.prototype.basePath), "undefined" == typeof SCAYT.CUSTOMSCAYT.includeRequiredUI && (SCAYT.CUSTOMSCAYT.includeRequiredUI = !0), window.scaytAlreadyLoaded && window.scaytAlreadyLoaded(), function(a, b) {
    "use strict";
    a.Dialog.add("scaytDialog", function(a) {
        function c(a, b) {
            for (var c = [], d = [], f = null, g = 0; g < b.length; g++) f = e.arrayFilter.call(a, function(a) {
                return a.id === b[g]
            })[0], f && c.push(f);
            d = e.arrayFilter.call(a, function(a) {
                return a.required
            });
            for (var g = 0; g < d.length; g++) {
                var h = !e.arrayFilter.call(c, function(a) {
                    return a.id === d[g].id
                })[0];
                h && c.push(d[g])
            }
            return c
        }
        var d = b.UILib,
            e = b.Utils,
            f = a.scaytOptions;
        a.subscribe("userDictionaryAction", function(b) {
            var c, d = (a.UILib, b.dialog),
                e = d.getUIElement("dictionaries", "dictionaryNote"),
                f = d.getUIElement("dictionaries", "dictionaryName"),
                g = a.getOption("userDictionaryName") || "";
            b.error ? ("" === b.name ? e.setHtml(a.getLocal("message_info_emptyDic")) : (c = a.getLocal("message_error_" + b.command + "Dic"), c = c.replace("%s", b.name), e.setHtml(c)), e.css({
                color: "#ef0000",
                "margin-bottom": "-5px"
            }), f.setValue(g ? g : "")) : (c = a.getLocal("message_success_" + b.command + "Dic"), c = c.replace("%s", b.name), e.setHtml(c), e.css({
                color: "#1E8914",
                "margin-bottom": "-5px"
            }))
        });
        var g = [{
                id: "options",
                title: a.getLocal("tab_options"),
                extraClass: "options",
                elements: [{
                    id: "scaytOptions",
                    type: "vbox",
                    children: [{
                        id: "ignore-all-caps-words",
                        type: "checkbox",
                        storable: !0,
                        label: a.getLocal("label_allCaps")
                    }, {
                        id: "ignore-domain-names",
                        type: "checkbox",
                        storable: !0,
                        label: a.getLocal("label_ignoreDomainNames")
                    }, {
                        id: "ignore-words-with-mixed-cases",
                        type: "checkbox",
                        storable: !0,
                        label: a.getLocal("label_mixedCase")
                    }, {
                        id: "ignore-words-with-numbers",
                        type: "checkbox",
                        storable: !0,
                        label: a.getLocal("label_mixedWithDigits")
                    }],
                    onShow: function() {
                        var b = this.getChildren(),
                            c = !1;
                        for (var d in b) c = a.getOption(d), b[d][c ? "check" : "uncheck"](), b[d].commit()
                    }
                }]
            }, {
                id: "languages",
                extraClass: "sc-tabset__tab-languages",
                title: a.getLocal("tab_languages"),
                elements: [{
                    id: "langHolder",
                    type: "hbox",
                    widths: ["45%", "45%"],
                    extraClass: "clrfix",
                    style: "width: 100%; margin-bottom: 10px;",
                    children: [{
                        id: "leftLangCol",
                        type: "vbox"
                    }, {
                        id: "rightLangCol",
                        type: "vbox",
                        style: "padding: 0 0 0 10px;"
                    }],
                    onShow: function() {
                        var b = "scaytLang_",
                            c = a.getOption("lang"),
                            d = this.getParentDialog().getUIElement("languages", b + c);
                        d && (d.check(), d.commit())
                    }
                }, {
                    id: "linkExternal",
                    type: "html",
                    style: "position: absolute; bottom: 15px; left: 15px;",
                    html: '<a href="http://www.webspellchecker.net/additional-languages-support.html" target="_blank" class="sc-link-external sc-focusable">' + a.getLocal("btn_moreLanguages") + "</a>"
                }]
            }, {
                id: "dictionaries",
                extraClass: "sc-tabset__tab-dictionaries",
                title: a.getLocal("tab_dictionaries"),
                onClick: function() {
                    var a = this.getParentDialog(),
                        b = a.getUIElement("dictionaries", "dictionaryNote");
                    b.setHtml(""), h.clearWordList.call(a), h.getUserDictionary.call(a), h.toggleDictionaryState.call(a, "wordsState")
                },
                elements: [{
                    id: "dictionaryNote",
                    type: "html",
                    html: ""
                }, {
                    id: "dictionaryActions",
                    type: "hbox",
                    widths: ["48%", "48%"],
                    style: "width: 100%;",
                    extraClass: "clrfix",
                    children: [{
                        id: "dictionaryName",
                        type: "text",
                        maxLength: "64",
                        placeholder: a.getLocal("placeholder_fieldNameDic"),
                        storable: !0,
                        onShow: function() {
                            var b = this.getParentDialog(),
                                c = a.getOption("userDictionaryName") || "";
                            b.getUIElement("dictionaries", "dictionaryNote").setHtml(""), this.setValue(c), h.toggleDictionaryState.call(b, c ? "dictionaryState" : "initialState")
                        }
                    }, {
                        id: "additionalButtons",
                        type: "hbox",
                        style: "width: 100%;",
                        extraClass: "sc-additional-buttons-holder",
                        children: [{
                            id: "removeDic",
                            type: "button",
                            extraClass: "sc-button__icon sc-button__icon_delete",
                            text: "&#65279;",
                            title: a.getLocal("btn_deleteDic"),
                            onClick: function() {
                                var b = this.getParentDialog(),
                                    c = b.getUIElement("dictionaries", "dictionaryName"),
                                    d = a.getOption("userDictionaryName");
                                a.fire("removeUserDictionary", {
                                    name: d,
                                    onSuccess: function(e) {
                                        c.setValue(""), e.error || h.toggleDictionaryState.call(b, "initialState"), e.dialog = b, e.command = "remove", e.name = d, a.fire("userDictionaryAction", e)
                                    },
                                    onError: function(c) {
                                        c.dialog = b, c.command = "remove", c.name = d, a.fire("userDictionaryAction", c)
                                    }
                                })
                            }
                        }, {
                            id: "renameDic",
                            type: "button",
                            extraClass: "sc-button__icon sc-button__icon_rename",
                            text: "&#65279;",
                            title: a.getLocal("btn_renameDic"),
                            onClick: function() {
                                var b = this.getParentDialog(),
                                    c = b.getUIElement("dictionaries", "dictionaryName").getValue();
                                a.fire("renameUserDictionary", {
                                    newName: c,
                                    onSuccess: function(d) {
                                        d.dialog = b, d.command = "rename", d.name = c, a.fire("userDictionaryAction", d)
                                    },
                                    onError: function(d) {
                                        d.dialog = b, d.command = "rename", d.name = c, a.fire("userDictionaryAction", d)
                                    }
                                })
                            }
                        }]
                    }]
                }, {
                    id: "udButtonsHolder",
                    type: "hbox",
                    extraClass: "clrfix",
                    style: "margin-top: -15px;",
                    children: [{
                        id: "createDic",
                        type: "button",
                        extraClass: "sc-button_grey",
                        text: a.getLocal("btn_createDic"),
                        title: a.getLocal("btn_createDic"),
                        onClick: function() {
                            var b = this.getParentDialog(),
                                c = b.getUIElement("dictionaries", "dictionaryName").getValue();
                            a.fire("createUserDictionary", {
                                name: c,
                                onSuccess: function(d) {
                                    d.error || h.toggleDictionaryState.call(b, "dictionaryState"), d.dialog = b, d.command = "create", d.name = c, a.fire("userDictionaryAction", d)
                                },
                                onError: function(d) {
                                    d.dialog = b, d.command = "create", d.name = c, a.fire("userDictionaryAction", d)
                                }
                            })
                        }
                    }, {
                        id: "restoreDic",
                        type: "button",
                        extraClass: "sc-button_grey",
                        text: a.getLocal("btn_connectDic"),
                        title: a.getLocal("btn_connectDic"),
                        onClick: function() {
                            var b = this.getParentDialog(),
                                c = b.getUIElement("dictionaries", "dictionaryName").getValue();
                            a.fire("restoreUserDictionary", {
                                name: c,
                                onSuccess: function(d) {
                                    !d.error && d.name ? h.toggleDictionaryState.call(b, "dictionaryState") : d.error = !0, d.dialog = b, d.command = "restore", d.name = c, a.fire("userDictionaryAction", d)
                                },
                                onError: function(d) {
                                    d.dialog = b, d.command = "restore", d.name = c, a.fire("userDictionaryAction", d)
                                }
                            })
                        }
                    }, {
                        id: "disconnectDic",
                        type: "button",
                        extraClass: "sc-button_grey",
                        text: a.getLocal("btn_disconnectDic"),
                        title: a.getLocal("btn_disconnectDic"),
                        onClick: function() {
                            var b = this.getParentDialog(),
                                c = b.getUIElement("dictionaries", "dictionaryName"),
                                d = a.getOption("userDictionaryName");
                            a.fire("disconnectFromUserDictionary", {}), c.setValue(""), h.toggleDictionaryState.call(b, "initialState"), a.fire("userDictionaryAction", {
                                dialog: b,
                                command: "disconnect",
                                name: d
                            })
                        }
                    }]
                }, {
                    id: "dicInfo",
                    type: "html",
                    style: "margin: 20px auto 5px; white-space:normal; line-height:1.7; font-size:11px;",
                    html: '<a href="http://scayt.com/user_manual/scayt_for_editable_controls_user_manual.pdf" target="_blank" class="sc-link-external sc-focusable">' + a.getLocal("btn_learnDictionary") + "</a>"
                }, {
                    id: "workWithWords",
                    type: "vbox",
                    extraClass: "sc-ud-words clrfix",
                    style: "width: 100%; height: 250px; margin-bottom: 0",
                    children: [{
                        id: "wordActions",
                        type: "hbox",
                        widths: ["48%", "48%"],
                        style: "width: 100%;",
                        extraClass: "clrfix",
                        children: [{
                            id: "addWordField",
                            type: "text",
                            maxLength: "64",
                            placeholder: a.getLocal("placeholder_fieldAddWord"),
                            onShow: function() {
                                this.setValue("")
                            },
                            onKeydown: function(a) {
                                var b = a.event.keyCode || a.event.which,
                                    c = this.getParentDialog(),
                                    d = c.getUIElement("dictionaries", "addWord");
                                13 === b && this.getValue() && !d.isDisabled() && d.onClick()
                            }
                        }, {
                            id: "addWordButton",
                            type: "hbox",
                            children: [{
                                id: "addWord",
                                type: "button",
                                extraClass: "sc-button_green",
                                text: a.getLocal("btn_add"),
                                title: a.getLocal("btn_add"),
                                onClick: function() {
                                    var b = this.getParentDialog(),
                                        c = b.getUIElement("dictionaries", "wordList"),
                                        d = b.getUIElement("dictionaries", "addWordField"),
                                        f = d.getValue(),
                                        g = a.getOption("punctuationRegExp"),
                                        h = /.\s\xA0/,
                                        i = new RegExp("[" + h.source + g.source + "]", "g"),
                                        j = this;
                                    if (f) {
                                        if (-1 !== f.search(i)) return void a.fire("userDictionaryAction", {
                                            dialog: b,
                                            command: "wordWithBannedSymbols",
                                            name: f,
                                            error: !0
                                        });
                                        if (c.inChildren(f)) return d.setValue(""), void a.fire("userDictionaryAction", {
                                            dialog: b,
                                            command: "wordAlreadyAdded",
                                            name: f
                                        });
                                        this.disable(), a.fire("addWordToUserDictionary", {
                                            word: f,
                                            onSuccess: function(g) {
                                                g.error || (d.setValue(""), c.addChild(f, !0)), g.dialog = b, g.command = "addWord", g.name = e.trunc(f, 16), j.enable(), a.fire("userDictionaryAction", g)
                                            },
                                            onError: function(c) {
                                                c.dialog = b, c.command = "addWord", c.name = e.trunc(f, 16), j.enable(), a.fire("userDictionaryAction", c)
                                            }
                                        })
                                    }
                                }
                            }]
                        }]
                    }, {
                        id: "wordList",
                        type: "itemList",
                        title: a.getLocal("btn_deleteWord"),
                        onClick: function(b) {
                            var c = b.event,
                                f = "data-ud-word",
                                g = d.parent(c.target)[0],
                                h = d.attr(g, f),
                                i = this.getParentDialog(),
                                j = i.getUIElement("dictionaries", "wordList"),
                                k = this;
                            d.hasClass(c.target, "sc-item-list__icon_close") && !this.isBlocked() && (this.block(), a.fire("deleteWordFromUserDictionary", {
                                word: h,
                                onSuccess: function(b) {
                                    b.error || j.removeChild(g, h), k.unblock(), b.dialog = i, b.command = "deleteWord", b.name = e.trunc(h, 16), a.fire("userDictionaryAction", b)
                                },
                                onError: function(b) {
                                    k.unblock(), b.dialog = i, b.command = "deleteWord", b.name = e.trunc(h, 16), a.fire("userDictionaryAction", b)
                                }
                            }))
                        },
                        children: []
                    }]
                }, {
                    id: "wordState",
                    type: "hbox",
                    extraClass: "clrfix",
                    style: "position: absolute; margin-bottom: 0; right: 15px; bottom: 15px",
                    children: [{
                        id: "goToDic",
                        type: "button",
                        extraClass: "sc-button_grey sc-button_full",
                        text: a.getLocal("btn_goToDic"),
                        title: a.getLocal("btn_goToDic"),
                        onClick: function() {
                            var b = this.getParentDialog(),
                                c = b.getUIElement("dictionaries", "dictionaryNote");
                            c.setHtml(""), h.clearWordList.call(this.getParentDialog()), h.getUserDictionary.call(this.getParentDialog()), h.toggleDictionaryState.call(b, "wordsState"), a.fire("afterTabShow", {})
                        }
                    }]
                }, {
                    id: "dictionarySettingsState",
                    type: "hbox",
                    extraClass: "clrfix",
                    style: "position: absolute; margin-bottom: 0; right: 15px; bottom: 15px;",
                    children: [{
                        id: "dictionaryPreferences",
                        type: "button",
                        extraClass: "sc-button_grey sc-button_full",
                        text: a.getLocal("btn_dictionaryPreferences"),
                        title: a.getLocal("btn_dictionaryPreferences"),
                        onClick: function() {
                            var b = this.getParentDialog(),
                                c = b.getUIElement("dictionaries", "dictionaryNote");
                            c.setHtml(""), a.getOption("userDictionaryName") ? h.toggleDictionaryState.call(b, "dictionaryState") : h.toggleDictionaryState.call(b, "initialState"), a.fire("afterTabShow", {})
                        }
                    }]
                }]
            }, {
                id: "about",
                title: a.getLocal("tab_about"),
                required: SCAYT.CUSTOMSCAYT.includeRequiredUI,
                extraClass: "about",
                elements: [{
                    type: "html",
                    id: "aboutBlock",
                    style: "margin: 5px;",
                    html: '<div class="sc-version-control-holder"><div class="sc-image-block"><img src="' + a.getOption("basePath") + a.getOption("scaytLogo") + '" alt="WebSpellChecker.net"></div><div class="sc-text-block"><h5>SCAYT 3 for Editable Controls</h5><p>' + a.getLocal("version") + a.getOption("scaytVersion") + '</p></div></div><div class="sc-copyrights">' + a.getLocal("text_copyrights") + "</div>"
                }]
            }],
            h = {
                title: a.getLocal("text_title"),
                tabs: c(g, f.uiTabs),
                minWidth: 500,
                onLoad: function(a) {
                    a.sender.dialogName === this.dialogName && h.renderLangList(this)
                },
                onClose: function(b) {
                    if (b.sender.dialogName === this.dialogName) {
                        var c = h.getOptionsToCommit(b);
                        a.fire("commitOptions", c)
                    }
                },
                renderLangList: function(b) {
                    var c, e, f, g = b.getUIElement("languages", "leftLangCol"),
                        h = b.getUIElement("languages", "rightLangCol"),
                        i = a.getOption("scaytLangList"),
                        j = {},
                        k = [],
                        l = 0;
                    j = d.extend({}, i.ltr, i.rtl);
                    for (e in j) k.push([e, j[e]]);
                    k.sort(function(a, b) {
                        var c = 0;
                        return a[1] > b[1] ? c = 1 : a[1] < b[1] && (c = -1), c
                    }), j = {};
                    for (var m = 0; m < k.length; m++) j[k[m][0]] = k[m][1];
                    c = Math.round(k.length / 2);
                    for (e in j) l++, f = c >= l ? g : h, f.addChild({
                        id: "scaytLang_" + e,
                        type: "radio",
                        storable: !0,
                        name: "scayt_lang",
                        label: j[e],
                        value: e
                    })
                },
                getOptionsToCommit: function(a) {
                    var b = a.sender,
                        c = {},
                        g = e.inArray(f.uiTabs, "options") ? b.getUIElement("options", "scaytOptions") : null,
                        h = e.inArray(f.uiTabs, "languages") ? b.getUIElement("languages", "leftLangCol") : null,
                        i = e.inArray(f.uiTabs, "languages") ? b.getUIElement("languages", "rightLangCol") : null,
                        j = {};
                    if (g) {
                        g = g.getChildren();
                        for (var k in g) g[k].isChanged() && (c[k] = g[k].isChecked())
                    }
                    if (h || i) {
                        j = d.extend(j, h && h.getChildren() || {}, i && i.getChildren() || {});
                        for (var k in j) if (j[k].isChecked() && j[k].isChanged()) {
                            c.lang = j[k].getValue();
                            break
                        }
                    }
                    return c
                },
                toggleDictionaryButtons: function(a) {
                    var b = this.getUIElement("dictionaries", "createDic"),
                        c = this.getUIElement("dictionaries", "removeDic"),
                        d = this.getUIElement("dictionaries", "renameDic"),
                        e = this.getUIElement("dictionaries", "restoreDic");
                    a ? (b.disable(), e.disable(), c.enable(), d.enable()) : (b.enable(), e.enable(), c.disable(), d.disable())
                },
                toggleDictionaryState: function(a) {
                    var b = this.getUIElement("dictionaries", "dictionarySettingsState"),
                        c = this.getUIElement("dictionaries", "wordState"),
                        d = this.getUIElement("dictionaries", "dictionaryActions"),
                        e = this.getUIElement("dictionaries", "udButtonsHolder"),
                        f = this.getUIElement("dictionaries", "createDic"),
                        g = this.getUIElement("dictionaries", "restoreDic"),
                        h = this.getUIElement("dictionaries", "disconnectDic"),
                        i = this.getUIElement("dictionaries", "removeDic"),
                        j = this.getUIElement("dictionaries", "renameDic"),
                        k = this.getUIElement("dictionaries", "dicInfo"),
                        l = this.getUIElement("dictionaries", "workWithWords");
                    switch (a) {
                        case "initialState":
                            b.hideElement(), c.showElement(), d.showElement(), e.showElement(), f.enable(), g.showElement(), h.hideElement(), i.disable(), j.disable(), k.showElement(), l.hideElement();
                            break;
                        case "wordsState":
                            b.showElement(), c.hideElement(), d.hideElement(), e.hideElement(), k.hideElement(), l.showElement();
                            break;
                        case "dictionaryState":
                            b.hideElement(), c.showElement(), d.showElement(), e.showElement(), f.disable(), g.hideElement(), h.showElement(), i.enable(), j.enable(), k.showElement(), l.hideElement()
                    }
                },
                clearWordList: function() {
                    var a = this.getUIElement("dictionaries", "wordList");
                    a.removeAllChild()
                },
                getUserDictionary: function(b) {
                    var c = this;
                    a.fire("getUserDictionary", {
                        name: b,
                        callback: function(a) {
                            a.error || h.renderWordList(a.wordlist, c)
                        }
                    })
                },
                renderWordList: function(a, b) {
                    for (var c = b.getUIElement("dictionaries", "wordList"), d = 0; d < a.length; d++) c.addChild(a[d])
                }
            };
        return h
    }), a.Dialog.add("pasteDialog", function(a) {
        var c, d = (b.UILib, {
            title: a.getLocal("btn_paste"),
            extraClass: "paste",
            minWidth: 500,
            tabs: [{
                id: "paste",
                elements: [{
                    id: "pasteContents",
                    type: "vbox",
                    children: [{
                        id: "messageInfoPaste",
                        type: "html",
                        html: '<p class="sc-cm-paste-message">' + a.getLocal("message_info_paste") + "</p>"
                    }, {
                        id: "pasteContainer",
                        type: "html",
                        html: '<div class="sc-cm-paste-holder sc-focusable" contenteditable="true" spellcheck="false"></div>'
                    }]
                }, {
                    id: "pasteAction",
                    type: "hbox",
                    extraClass: "clrfix",
                    style: "position: absolute; margin-bottom: 0; right: 15px; bottom: 15px",
                    children: [{
                        id: "pasteText",
                        type: "button",
                        extraClass: "sc-button_green",
                        text: a.getLocal("btn_paste"),
                        title: a.getLocal("btn_paste"),
                        onClick: function() {
                            var b = this.getParentDialog(),
                                d = c.innerHTML;
                            b.hide(), b.fire("restoreSelection"), setTimeout(function() {
                                a.fire("pasteProcessed", {
                                    contentType: "auto",
                                    text: d,
                                    pasteInto: a.getOption("container")
                                })
                            }, 0)
                        }
                    }]
                }]
            }],
            onLoad: function(a) {
                a.sender.dialogName === this.dialogName && (c = this.find(".sc-cm-paste-holder")[0])
            },
            onShow: function(b) {
                b.sender.dialogName === this.dialogName && (c.innerHTML = "", a.fire({
                    eventType: "focus",
                    element: c
                }))
            }
        });
        return d
    })
}(SCAYT.UI, SCAYT.prototype);